From ed4d04ba0722df9d1c802a5b344b762669810cd0 Mon Sep 17 00:00:00 2001 From: Sehong Na Date: Sat, 31 May 2014 12:46:03 +0900 Subject: [PATCH 1/1] Initialize Tizen 2.3 --- COPYING | 142 + ChangeLog | 1662 ++++++++ INSTALL | 291 ++ Makefile.am | 49 + README | 26 + autogen.sh | 12 + compile | 310 ++ configure.ac | 115 + docbook.am | 105 + include/Makefile.am | 74 + include/X11/Xaw/AllWidgets.h | 37 + include/X11/Xaw/AsciiSink.h | 77 + include/X11/Xaw/AsciiSinkP.h | 95 + include/X11/Xaw/AsciiSrc.h | 172 + include/X11/Xaw/AsciiSrcP.h | 139 + include/X11/Xaw/AsciiText.h | 123 + include/X11/Xaw/AsciiTextP.h | 164 + include/X11/Xaw/Box.h | 102 + include/X11/Xaw/BoxP.h | 97 + include/X11/Xaw/Cardinals.h | 42 + include/X11/Xaw/Command.h | 116 + include/X11/Xaw/CommandP.h | 111 + include/X11/Xaw/Dialog.h | 98 + include/X11/Xaw/DialogP.h | 100 + include/X11/Xaw/Form.h | 167 + include/X11/Xaw/FormP.h | 139 + include/X11/Xaw/Grip.h | 96 + include/X11/Xaw/GripP.h | 85 + include/X11/Xaw/Label.h | 132 + include/X11/Xaw/LabelP.h | 115 + include/X11/Xaw/List.h | 234 ++ include/X11/Xaw/ListP.h | 115 + include/X11/Xaw/MenuButtoP.h | 79 + include/X11/Xaw/MenuButton.h | 89 + include/X11/Xaw/MultiSink.h | 110 + include/X11/Xaw/MultiSinkP.h | 138 + include/X11/Xaw/MultiSrc.h | 130 + include/X11/Xaw/MultiSrcP.h | 179 + include/X11/Xaw/Paned.h | 258 ++ include/X11/Xaw/PanedP.h | 176 + include/X11/Xaw/Panner.h | 105 + include/X11/Xaw/PannerP.h | 106 + include/X11/Xaw/Porthole.h | 61 + include/X11/Xaw/PortholeP.h | 62 + include/X11/Xaw/Repeater.h | 73 + include/X11/Xaw/RepeaterP.h | 82 + include/X11/Xaw/Reports.h | 55 + include/X11/Xaw/Scrollbar.h | 133 + include/X11/Xaw/ScrollbarP.h | 103 + include/X11/Xaw/Simple.h | 113 + include/X11/Xaw/SimpleMenP.h | 99 + include/X11/Xaw/SimpleMenu.h | 171 + include/X11/Xaw/SimpleP.h | 98 + include/X11/Xaw/Sme.h | 71 + include/X11/Xaw/SmeBSB.h | 96 + include/X11/Xaw/SmeBSBP.h | 92 + include/X11/Xaw/SmeLine.h | 69 + include/X11/Xaw/SmeLineP.h | 73 + include/X11/Xaw/SmeP.h | 88 + include/X11/Xaw/StripCharP.h | 104 + include/X11/Xaw/StripChart.h | 116 + include/X11/Xaw/Template.c | 195 + include/X11/Xaw/Template.h | 67 + include/X11/Xaw/TemplateP.h | 65 + include/X11/Xaw/Text.h | 370 ++ include/X11/Xaw/TextP.h | 317 ++ include/X11/Xaw/TextSink.h | 359 ++ include/X11/Xaw/TextSinkP.h | 300 ++ include/X11/Xaw/TextSrc.h | 275 ++ include/X11/Xaw/TextSrcP.h | 258 ++ include/X11/Xaw/Tip.h | 118 + include/X11/Xaw/TipP.h | 75 + include/X11/Xaw/Toggle.h | 179 + include/X11/Xaw/ToggleP.h | 92 + include/X11/Xaw/Tree.h | 135 + include/X11/Xaw/TreeP.h | 137 + include/X11/Xaw/VendorEP.h | 81 + include/X11/Xaw/Viewport.h | 118 + include/X11/Xaw/ViewportP.h | 107 + include/X11/Xaw/XawImP.h | 210 + include/X11/Xaw/XawInit.h | 62 + man/Makefile.am | 41 + man/Xaw.man | 629 +++ old-doc/CHANGES | 153 + old-doc/Changelog | 1370 ++++++ packaging/libXaw.spec | 80 + specs/AsciiSink.xml | 141 + specs/AsciiSource.xml | 368 ++ specs/AsciiText.xml | 450 ++ specs/Box.xml | 346 ++ specs/CH1.xml | 725 ++++ specs/CH2.xml | 1892 +++++++++ specs/CH3.xml | 123 + specs/CH4.xml | 102 + specs/CH5.xml | 397 ++ specs/CH6.xml | 117 + specs/CH7.xml | 167 + specs/Command.xml | 525 +++ specs/Dialog.xml | 692 +++ specs/Form.xml | 531 +++ specs/Grip.xml | 357 ++ specs/Label.xml | 345 ++ specs/List.xml | 872 ++++ specs/Makefile.am | 61 + specs/MenuButton.xml | 567 +++ specs/Paned.xml | 1213 ++++++ specs/Panner.xml | 734 ++++ specs/Porthole.xml | 306 ++ specs/Repeater.xml | 558 +++ specs/Scrollbar.xml | 884 ++++ specs/Simple.xml | 252 ++ specs/SimpleMenu.xml | 790 ++++ specs/Sme.xml | 207 + specs/SmeBSB.xml | 310 ++ specs/SmeLine.xml | 148 + specs/StripChart.xml | 435 ++ specs/TPage_Credits.xml | 90 + specs/Template.xml | 407 ++ specs/Template_private_header_file.xml | 87 + specs/Template_public_header_file.xml | 112 + specs/Template_widget_source_file.xml | 208 + specs/Text.xml | 326 ++ specs/TextActions.xml | 976 +++++ specs/TextActions_default_translation_bindings.xml | 85 + specs/TextActions_text_widget_actions.xml | 891 ++++ specs/TextCustom.xml | 123 + specs/TextFuncs.xml | 856 ++++ specs/TextSink.xml | 917 ++++ specs/TextSource.xml | 620 +++ specs/Toggle.xml | 773 ++++ specs/Tree.xml | 404 ++ specs/Viewport.xml | 391 ++ specs/libXaw.xml | 89 + src/Actions.c | 1136 +++++ src/AllWidgets.c | 109 + src/AsciiSink.c | 1948 +++++++++ src/AsciiSrc.c | 1888 +++++++++ src/AsciiText.c | 357 ++ src/Box.c | 673 +++ src/Command.c | 657 +++ src/Converters.c | 698 ++++ src/Dialog.c | 460 ++ src/DisplayList.c | 2255 ++++++++++ src/Form.c | 1106 +++++ src/Grip.c | 185 + src/Label.c | 821 ++++ src/List.c | 1270 ++++++ src/Makefile.am | 142 + src/MenuButton.c | 271 ++ src/MultiSink.c | 975 +++++ src/MultiSrc.c | 1617 +++++++ src/OS.c | 53 + src/Paned.c | 2063 +++++++++ src/Panner.c | 1079 +++++ src/Pixmap.c | 991 +++++ src/Porthole.c | 376 ++ src/Private.h | 152 + src/Repeater.c | 298 ++ src/Scrollbar.c | 882 ++++ src/Simple.c | 499 +++ src/SimpleMenu.c | 1829 ++++++++ src/Sme.c | 269 ++ src/SmeBSB.c | 769 ++++ src/SmeLine.c | 264 ++ src/StripChart.c | 576 +++ src/Text.c | 4157 ++++++++++++++++++ src/TextAction.c | 4399 ++++++++++++++++++++ src/TextPop.c | 1549 +++++++ src/TextSink.c | 1828 ++++++++ src/TextSrc.c | 2008 +++++++++ src/TextTr.c | 158 + src/Tip.c | 637 +++ src/Toggle.c | 628 +++ src/Tree.c | 1014 +++++ src/Vendor.c | 524 +++ src/Viewport.c | 1099 +++++ src/XawI18n.c | 105 + src/XawI18n.h | 118 + src/XawIm.c | 1609 +++++++ src/XawInit.c | 97 + src/sharedlib.c | 173 + xaw6.pc.in | 12 + xaw7.pc.in | 12 + 183 files changed, 83029 insertions(+) create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 README create mode 100755 autogen.sh create mode 100755 compile create mode 100644 configure.ac create mode 100644 docbook.am create mode 100644 include/Makefile.am create mode 100644 include/X11/Xaw/AllWidgets.h create mode 100644 include/X11/Xaw/AsciiSink.h create mode 100644 include/X11/Xaw/AsciiSinkP.h create mode 100644 include/X11/Xaw/AsciiSrc.h create mode 100644 include/X11/Xaw/AsciiSrcP.h create mode 100644 include/X11/Xaw/AsciiText.h create mode 100644 include/X11/Xaw/AsciiTextP.h create mode 100644 include/X11/Xaw/Box.h create mode 100644 include/X11/Xaw/BoxP.h create mode 100644 include/X11/Xaw/Cardinals.h create mode 100644 include/X11/Xaw/Command.h create mode 100644 include/X11/Xaw/CommandP.h create mode 100644 include/X11/Xaw/Dialog.h create mode 100644 include/X11/Xaw/DialogP.h create mode 100644 include/X11/Xaw/Form.h create mode 100644 include/X11/Xaw/FormP.h create mode 100644 include/X11/Xaw/Grip.h create mode 100644 include/X11/Xaw/GripP.h create mode 100644 include/X11/Xaw/Label.h create mode 100644 include/X11/Xaw/LabelP.h create mode 100644 include/X11/Xaw/List.h create mode 100644 include/X11/Xaw/ListP.h create mode 100644 include/X11/Xaw/MenuButtoP.h create mode 100644 include/X11/Xaw/MenuButton.h create mode 100644 include/X11/Xaw/MultiSink.h create mode 100644 include/X11/Xaw/MultiSinkP.h create mode 100644 include/X11/Xaw/MultiSrc.h create mode 100644 include/X11/Xaw/MultiSrcP.h create mode 100644 include/X11/Xaw/Paned.h create mode 100644 include/X11/Xaw/PanedP.h create mode 100644 include/X11/Xaw/Panner.h create mode 100644 include/X11/Xaw/PannerP.h create mode 100644 include/X11/Xaw/Porthole.h create mode 100644 include/X11/Xaw/PortholeP.h create mode 100644 include/X11/Xaw/Repeater.h create mode 100644 include/X11/Xaw/RepeaterP.h create mode 100644 include/X11/Xaw/Reports.h create mode 100644 include/X11/Xaw/Scrollbar.h create mode 100644 include/X11/Xaw/ScrollbarP.h create mode 100644 include/X11/Xaw/Simple.h create mode 100644 include/X11/Xaw/SimpleMenP.h create mode 100644 include/X11/Xaw/SimpleMenu.h create mode 100644 include/X11/Xaw/SimpleP.h create mode 100644 include/X11/Xaw/Sme.h create mode 100644 include/X11/Xaw/SmeBSB.h create mode 100644 include/X11/Xaw/SmeBSBP.h create mode 100644 include/X11/Xaw/SmeLine.h create mode 100644 include/X11/Xaw/SmeLineP.h create mode 100644 include/X11/Xaw/SmeP.h create mode 100644 include/X11/Xaw/StripCharP.h create mode 100644 include/X11/Xaw/StripChart.h create mode 100644 include/X11/Xaw/Template.c create mode 100644 include/X11/Xaw/Template.h create mode 100644 include/X11/Xaw/TemplateP.h create mode 100644 include/X11/Xaw/Text.h create mode 100644 include/X11/Xaw/TextP.h create mode 100644 include/X11/Xaw/TextSink.h create mode 100644 include/X11/Xaw/TextSinkP.h create mode 100644 include/X11/Xaw/TextSrc.h create mode 100644 include/X11/Xaw/TextSrcP.h create mode 100644 include/X11/Xaw/Tip.h create mode 100644 include/X11/Xaw/TipP.h create mode 100644 include/X11/Xaw/Toggle.h create mode 100644 include/X11/Xaw/ToggleP.h create mode 100644 include/X11/Xaw/Tree.h create mode 100644 include/X11/Xaw/TreeP.h create mode 100644 include/X11/Xaw/VendorEP.h create mode 100644 include/X11/Xaw/Viewport.h create mode 100644 include/X11/Xaw/ViewportP.h create mode 100644 include/X11/Xaw/XawImP.h create mode 100644 include/X11/Xaw/XawInit.h create mode 100644 man/Makefile.am create mode 100644 man/Xaw.man create mode 100644 old-doc/CHANGES create mode 100644 old-doc/Changelog create mode 100644 packaging/libXaw.spec create mode 100644 specs/AsciiSink.xml create mode 100644 specs/AsciiSource.xml create mode 100644 specs/AsciiText.xml create mode 100644 specs/Box.xml create mode 100644 specs/CH1.xml create mode 100644 specs/CH2.xml create mode 100644 specs/CH3.xml create mode 100644 specs/CH4.xml create mode 100644 specs/CH5.xml create mode 100644 specs/CH6.xml create mode 100644 specs/CH7.xml create mode 100644 specs/Command.xml create mode 100644 specs/Dialog.xml create mode 100644 specs/Form.xml create mode 100644 specs/Grip.xml create mode 100644 specs/Label.xml create mode 100644 specs/List.xml create mode 100644 specs/Makefile.am create mode 100644 specs/MenuButton.xml create mode 100644 specs/Paned.xml create mode 100644 specs/Panner.xml create mode 100644 specs/Porthole.xml create mode 100644 specs/Repeater.xml create mode 100644 specs/Scrollbar.xml create mode 100644 specs/Simple.xml create mode 100644 specs/SimpleMenu.xml create mode 100644 specs/Sme.xml create mode 100644 specs/SmeBSB.xml create mode 100644 specs/SmeLine.xml create mode 100644 specs/StripChart.xml create mode 100644 specs/TPage_Credits.xml create mode 100644 specs/Template.xml create mode 100644 specs/Template_private_header_file.xml create mode 100644 specs/Template_public_header_file.xml create mode 100644 specs/Template_widget_source_file.xml create mode 100644 specs/Text.xml create mode 100644 specs/TextActions.xml create mode 100644 specs/TextActions_default_translation_bindings.xml create mode 100644 specs/TextActions_text_widget_actions.xml create mode 100644 specs/TextCustom.xml create mode 100644 specs/TextFuncs.xml create mode 100644 specs/TextSink.xml create mode 100644 specs/TextSource.xml create mode 100644 specs/Toggle.xml create mode 100644 specs/Tree.xml create mode 100644 specs/Viewport.xml create mode 100644 specs/libXaw.xml create mode 100644 src/Actions.c create mode 100644 src/AllWidgets.c create mode 100644 src/AsciiSink.c create mode 100644 src/AsciiSrc.c create mode 100644 src/AsciiText.c create mode 100644 src/Box.c create mode 100644 src/Command.c create mode 100644 src/Converters.c create mode 100644 src/Dialog.c create mode 100644 src/DisplayList.c create mode 100644 src/Form.c create mode 100644 src/Grip.c create mode 100644 src/Label.c create mode 100644 src/List.c create mode 100644 src/Makefile.am create mode 100644 src/MenuButton.c create mode 100644 src/MultiSink.c create mode 100644 src/MultiSrc.c create mode 100644 src/OS.c create mode 100644 src/Paned.c create mode 100644 src/Panner.c create mode 100644 src/Pixmap.c create mode 100644 src/Porthole.c create mode 100644 src/Private.h create mode 100644 src/Repeater.c create mode 100644 src/Scrollbar.c create mode 100644 src/Simple.c create mode 100644 src/SimpleMenu.c create mode 100644 src/Sme.c create mode 100644 src/SmeBSB.c create mode 100644 src/SmeLine.c create mode 100644 src/StripChart.c create mode 100644 src/Text.c create mode 100644 src/TextAction.c create mode 100644 src/TextPop.c create mode 100644 src/TextSink.c create mode 100644 src/TextSrc.c create mode 100644 src/TextTr.c create mode 100644 src/Tip.c create mode 100644 src/Toggle.c create mode 100644 src/Tree.c create mode 100644 src/Vendor.c create mode 100644 src/Viewport.c create mode 100644 src/XawI18n.c create mode 100644 src/XawI18n.h create mode 100644 src/XawIm.c create mode 100644 src/XawInit.c create mode 100644 src/sharedlib.c create mode 100644 xaw6.pc.in create mode 100644 xaw7.pc.in diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..aeeeda3 --- /dev/null +++ b/COPYING @@ -0,0 +1,142 @@ +Copyright 1985-1990, 1994, 1998 The Open Group +Copyright 2003-2004 Roland Mainz + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright (c) 1998-1999 by The XFree86 Project, Inc. + +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 XFREE86 PROJECT 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. + +Except as contained in this notice, the name of the XFree86 Project shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from the +XFree86 Project. + + +Copyright 1991 by OMRON Corporation + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of OMRON not be used in advertising or +publicity pertaining to distribution of the software without specific, +written prior permission. OMRON makes no representations about the +suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + +Copyright 1987-1998 by Digital Equipment Corporation, Maynard, Massachusetts. +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + +Copyright 1989 Prentice Hall + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that the above +copyright notice appear in all copies and that both the copyright notice +and this permission notice appear in supporting documentation. + +Prentice Hall and the authors disclaim all warranties with regard +to this software, including all implied warranties of merchantability and +fitness. In no event shall Prentice Hall or the authors be liable +for any special, indirect or cosequential damages or any damages whatsoever +resulting from loss of use, data or profits, whether in an action of +contract, negligence or other tortious action, arising out of or in +connection with the use or performance of this software. + + +Copyright 1985, 1986, 1987, 1988, 1989, 1991, 1994 X Consortium + +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 +X CONSORTIUM 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. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +Copyright 1985, 1986, 1987, 1988, 1989, 1991 +Digital Equipment Corporation, Maynard, Massachusetts. + +Permission to use, copy, modify and distribute this documentation for any +purpose and without fee is hereby granted, provided that the above copyright +notice appears in all copies and that both that copyright notice and this +permission notice appear in supporting documentation, and that the name of +Digital not be used in in advertising or publicity pertaining +to distribution of the software without specific, written prior permission. +Digital makes no representations about the suitability of the +software described herein for any purpose. +It is provided ``as is'' without express or implied warranty. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..5e7e8f5 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,1662 @@ +commit ffaad7ee2ef6e06b4585567df04f6b64356fb6fe +Author: Alan Coopersmith +Date: Fri Jun 1 20:31:30 2012 -0700 + + libXaw 1.0.11 + + Signed-off-by: Alan Coopersmith + +commit 52081b462ff7d1844d014bf9be887197caa88160 +Author: Alan Coopersmith +Date: Sat May 26 15:07:07 2012 -0700 + + Only call XawStackFree if XawStackAlloc was used for allocation + + In FormParagraph() in TextAction.c, the #if OLDXAW case always uses + fixed length buffers, while the !OLDXAW case uses XawStackAlloc & + XawStackFree to switch to dynamic allocations when the buffers aren't + large enough. + + A couple instances of XawStackFree slipped into the wrong side of + the #if checks though, so move them back where they belong. Also + reset pos afterwards, in the case we continue and may use it again, + to avoid the chance of a double free. + + Found by the Parfait 0.5.0.1 bug checking tool: + + Error: Free memory not allocated dynamically by alloc (CWE 590) + Free() was called on a pointer 'buf' to the auto variable 'buf'. Free() must only be used on dynamically allocated memory + at line 3946 of TextAction.c in function 'FormParagraph'. + 'buf' allocated at line 0 as auto variable. + at line 4000 of TextAction.c in function 'FormParagraph'. + 'buf' allocated at line 0 as auto variable. + Error: Use after free (CWE 416) + Use after free of pointer '&buf' + at line 3995 of TextAction.c in function 'FormParagraph'. + Previously freed at line 3946 with XtFree. + Error: Use after free + Double free (CWE 415): Double free of pointer '&buf' in call to XtFree + at line 4000 of TextAction.c in function 'FormParagraph'. + Previously freed at line 3946 with XtFree. + Double free (CWE 415): Double free of pointer '' in call to XtFree + at line 4000 of TextAction.c in function 'FormParagraph'. + Previously freed at line 3946 with XtFree. + + Signed-off-by: Alan Coopersmith + Acked-by: pcpa + +commit ca35cff72a3100c9367b7e7f4811117c8733b8be +Author: Alan Coopersmith +Date: Sat May 26 14:44:26 2012 -0700 + + Correct order of arguments to XawStackFree() + + XawStackAlloc() & XawStackFree() are macros to automate the process of + using a fixed size stack buffer for strings smaller than the buffer size, + and allocating/freeing memory for larger strings. + + XawStackFree is defined in src/Private.h as taking (pointer, stk_buffer) + and freeing pointer if it's not pointing to the stack buffer. + + Most of the calls of this macro get the ordering right, but a couple + got it reversed, passing a stack buffer to free() instead of the + allocated pointer. + + Found by the Parfait 0.5.0.1 bug checking tool: + + Error: Free memory not allocated dynamically by alloc (CWE 590) + Free() was called on a pointer 'buf' to the auto variable 'buf'. Free() must only be used on dynamically allocated memory + at line 2281 of TextAction.c in function 'DoFormatText'. + 'buf' allocated at line 0 as auto variable. + at line 2296 of TextAction.c in function 'DoFormatText'. + 'buf' allocated at line 0 as auto variable. + + Signed-off-by: Alan Coopersmith + Acked-by: pcpa + +commit 11c3a104141e1a4946ad949dfb5514df0b66a031 +Author: pcpa +Date: Tue May 22 20:42:32 2012 -0300 + + Correct undefined behavior access to out of scope pointer contents. + + This problem is triggered in gcc 4.7 DCE (dead code elimination). + In the Xaw code, the local constant "String" is not guaranteed to + have global scope. + The problem was found when debugging the reason xedit built with + gcc 4.7 would be very unstable, and that happens regardless of using + a libXaw built with gcc 4.6. + + Signed-off-by: pcpa + Signed-off-by: Alan Coopersmith + +commit b16cc35e551860a0bff54c47b33317536ddeae52 +Author: Alan Coopersmith +Date: Thu Mar 22 19:51:33 2012 -0700 + + libXaw 1.0.10 + + Signed-off-by: Alan Coopersmith + +commit 8a78d3aef0f6f1f51997468daf5f67231f4a3ecd +Author: Matt Turner +Date: Wed Feb 1 13:44:05 2012 -0500 + + Include headers instead of using extern definitions + + Signed-off-by: Matt Turner + +commit 49c0a2441946f0d70fbd2612f193c95b84dde102 +Author: Jeremy Huddleston +Date: Tue Nov 1 20:47:34 2011 -0700 + + Build fix for -Werror=pointer-to-int-cast + + Signed-off-by: Jeremy Huddleston + +commit fe00db0ecafd95f6e1353b1d5f11ee6012a9b64c +Author: Matt Dew +Date: Wed Oct 5 22:33:05 2011 -0600 + + Cleanup IDs and links in doc + + 1 - fix the capitalization of the ID attributes to match either the + or <funcdef> string it goes with. + 2 - fix any <linkend>'s that were affected by 1. + 3 - any <function> in the docs that has an actual funcdef, + will become an olink. + + Signed-off-by: Matt Dew <marcoz@osource.org> + +commit c8e8838702ba8ae0a8100c7f1bd94ce9932339de +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Mon Sep 19 16:25:43 2011 -0400 + + specs: refactor multi license legal text + + Also restore lost information. + There was no version number for this spec as in many of the docs. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 37ffe69b10ae29e8f91de6ef647d06804b9d159b +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Sep 16 22:13:37 2011 -0700 + + Strip trailing whitespace + + Performed with: find * -type f | xargs perl -i -p -e 's{[ \t]+$}{}' + git diff -w & git diff -b show no diffs from this change + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit 6c628c605e4f58be3a84edc5273a0dd88363a770 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Tue Sep 13 17:12:59 2011 -0400 + + specs: fix orphan author affiliation. + + It belongs to Chris Peterson formerly of MIT + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit e07f1d83079eb90ea91e3ff120ad747b1cc78bfb +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Mon Sep 12 16:54:45 2011 -0400 + + docs: use the &fullrelvers; entity to set X11 release information + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 5b1f776e84108bce397cc6721ee176c3bb5592ad +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Sep 11 19:49:53 2011 -0400 + + docs: remove <productnumber> which is not used by default + + This element is not rendered by default on the title. A template + customization is required to display it. + X Window System does not have a product number. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 038802c68090dd3a75405178516017d80a51ecdf +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Thu Sep 8 20:00:00 2011 -0400 + + docbook.am: embed css styles inside the HTML HEAD element + + Rather than referring to the external xorg.css stylesheet, embed the content + of the file in the html output produced. This is accomplished by using + version 1.10 of xorg-xhtml.xsl. + + This makes the whole html docs tree much more relocatable. + In addition, it eliminates xorg.css as a runtime file which makes + xorg-sgml-doctools a build time only package. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit e24d546c5da599f63cc2ff40626b58c1183ed27a +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Wed Sep 7 10:31:04 2011 -0400 + + docbook.am: global maintenance update - entities, images and olinking + + Adding support in libX11 for html chunking caused a reorg of docbook.am + as well as the xorg-sgml-doctools masterdb for olinking. + The parameter img.src.path is added for pdf images. + A searchpath to the root builddir is added for local entities, if present. + + The docbook.am makefile hides all the details and is identical for + all 22 modules having DocBook documentation. It is included by a thin + Makefile.am which requires no docbook knowledge. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit a6c814b6d02e3f28f1d015678bd3d944ff8dfb10 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Thu Sep 1 14:01:02 2011 -0400 + + Remove include directive to <X11/Xaw> + + The -I directive to include/X11/Xaw is removed which will alert + developers not to include header files with quotes unless they are in + the /src directory. + + Currently no offending includes were found. + + Tested-by: Yaakov Selkowitz <yselkowitz@users.sourceforge.net> + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 86444aeda526e957e1d7adc90625f24e263aa7ea +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sat Jun 18 10:22:19 2011 -0400 + + man page: replace hard coded section number with __libmansuffix__ + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 66e450fdbb58b77641351e3c11631fdde86bf205 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Jun 12 18:38:44 2011 -0400 + + Install xml versions of specs even if HAVE_XMLTO is false + + DocBook/XML input source is also a usefull output format that can be viewed + with an XML viewer or editor and by some O/S help system. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit f3d7c3c5d9f142149d3217682667b32c3d0ded8d +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Jun 5 16:27:36 2011 -0400 + + Install target dbs alongside generated documents + + This matches a change in xorg-sgml-docs whereby the masterdb will look for + the target dbs into the same location as the generated documents. + + The target dbs are now installed alongside the generated documents. + Previously they are installed in $prefix/sgml/X11/dbs alongside masterdb which + has the potential of installing outside the package prefix and cause + distcheck to fail when user does not have write permission in this package. + + Requires XORG_CHECK_SGML_DOCTOOLS(1.8) which was released 2011-06-11 + +commit 39ffb88b3a6523e9258bc6e4f3948a09e63b269f +Author: Matt Dew <marcoz@osource.org> +Date: Tue May 31 20:03:23 2011 -0600 + + Add id attributes to funcsynopsis to allow other docs to olink to them. + + Signed-off-by: Matt Dew <marcoz@osource.org> + Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Gaetan Nadon <memsize@videotron.ca> + +commit f5823ff8ed5bd280e7858116c3cec5d97184b175 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sat May 28 08:48:10 2011 -0700 + + Correct path to examples in X11R5 contrib archive + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit 7d01dd4176b8ae1664218da8e197ef49d1efd05a +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri May 27 20:35:28 2011 -0700 + + Bug 37536: Documentation refers to invalid contrib/examples/mit/Xaw + + https://bugs.freedesktop.org/show_bug.cgi?id=37536 + + Update text to point to the latest distributed copy I found, in the + X11R5 contrib archives. + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit cfa8e377352d5b9d5dbddc75de8314a509f51224 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Feb 27 15:06:18 2011 -0500 + + Documentation: add Docbook external references support + + When writing technical documentation, it is often necessary to cross + reference to other information. When that other information is not in the + current document, additional support is needed, namely <olink>. + + A new feature with version 1.7 of xorg-sgml-doctools adds references to + other documents within or outside this package. + + This patch adds technical support for this feature but does not change + the content of the documentation as seen by the end user. + + Each book or article must generate a database containing the href + of sections that can be referred to from another document. This database + is installed in DATAROOTDIR/sgml/X11/dbs. There is a requirement that + the value of DATAROOTDIR for xorg-sgml-doctools and for the package + documentation is the same. This forms a virtual document tree. + + This database is consulted by other documents while they are being generated + in order to fulfill the missing information for linking. + Refer to the xorg-sgml-doctools for further technical information. + + Co-authored-by: Matt Dew <marcoz@osource.org> + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit a1c8ddc087715876cce1c86f837f7b13b49696aa +Author: Glenn Burkhardt <gbburkhardt@verizon.net> +Date: Fri Dec 3 17:22:42 2010 -0500 + + fix potential infinte loop in XawBoxQueryGeometry() (bug 11569) + + Originally sent to xorg@ back in July 2007. + http://lists.x.org/archives/xorg/2007-July/025997.html + +commit 38dce0209303b48054c884508633b4ce0d52a819 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Thu Jan 27 22:40:02 2011 -0800 + + Convert XmuSnprintf calls to just plain snprintf + + All supported platforms have native snprintf + + Remove #include <X11/Xmu/SysUtil.h> since it only defines XmuSnprintf + and the unused XmuGethostname + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit 83e4910b379cb9b9d69a0438eba3322470afda24 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Thu Jan 27 22:35:46 2011 -0800 + + Typo fix: sintax error -> syntax error + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit bd78cc3b4afec713fcef114b5f12186d749fdb17 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Wed Feb 2 11:43:41 2011 -0500 + + config: comment, minor upgrade and layout configure.ac + + Group statements per section as per Autoconf standard layout + Autoconf recommends not using dnl instead of # for comments + No functional configuration changes + + This helps automated maintenance and release activities. + Details can be found in http://wiki.x.org/wiki/NewModuleGuidelines + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 449ab92d83a972ba28ffda0ae198a6c8e4b00e78 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Fri Jan 28 16:07:07 2011 -0500 + + config: replace deprecated AC_HELP_STRING with AS_HELP_STRING + + This silences an Automake warning. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit b73a5ea91d0b3bb61ee8e7aa26ff178fd5b72209 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Fri Jan 28 14:59:04 2011 -0500 + + config: remove unrequired AC_HEADER_STDC + + Autoconf says: + "This macro is obsolescent, as current systems have conforming + header files. New programs need not use this macro". + +commit 03457873474dfc90e5f2322facbd6032a1312086 +Author: Roberto Branciforti <rbbrnc@gmail.com> +Date: Wed Jan 12 22:36:06 2011 +0100 + + Removing trailing white spaces + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit 8ac146ce96cfa133b788b1ffdd13fe0b648ee4fc +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Tue Jan 11 17:07:08 2011 -0800 + + libXaw 1.0.9 + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit e7a9b0302f7cb84015e8f612e5b65694d785b2d8 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Nov 21 09:33:46 2010 -0500 + + config: prevent config.status from being generated three times + + AC_OUTPUT with parameters is deprecated, use AC_CONFIG_FILES. + + Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Tested-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 55fc7aa22197350d9cd1039e0398132a63d3589f +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sat Nov 20 20:10:12 2010 -0800 + + Check for getpagesize() with autoconf instead of #ifdef osname + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Julien Cristau <jcristau@debian.org> + Reviewed-by: Gaetan Nadon <memsize@videotron.ca> + Tested-by: Gaetan Nadon <memsize@videotron.ca> + +commit b2e86875d03e349a4c85135e4cf41b26b99b083e +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sat Nov 20 20:06:04 2010 -0800 + + convert header checks/ifdefs to autoconf standard AC_CHECK_HEADERS + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Julien Cristau <jcristau@debian.org> + Reviewed-by: Gaetan Nadon <memsize@videotron.ca> + Tested-by: Gaetan Nadon <memsize@videotron.ca> + +commit 41bf7992c45c6766c5982b3500b03d9c1b1fab87 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sat Nov 20 19:54:54 2010 -0800 + + config: replace deprecated AM_CONFIG_HEADER with AC_CONFIG_HEADERS + + Regroup AC statements under the Autoconf initialization section. + Regroup AM statements under the Automake initialization section. + Regroup XORG statements under the Xorg macros section. + Add missing AC_CONFIG_SRCDIR + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit f85d4342cbfbb58764e24e202f3a7c95eaba3d77 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sat Nov 20 19:52:41 2010 -0800 + + config: Remove unnecessary calls from configure.ac + + AC_PROG_CC is provided by XORG_DEFAULT_OPTIONS now + PKG_CONFIG_MODULES handles AC_SUBST of the CFLAGS & LIBS variables + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit 394a0c49c849e497cbcb987154ff796eb34f4820 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Thu Nov 11 23:30:22 2010 -0800 + + specs/CH6.xml: Remove stray quote in chapter title + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit e9da4e6268b2cfbda793435caedc6403b2a918f0 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Tue Nov 9 13:04:44 2010 -0500 + + config: HTML file generation: use the installed copy of xorg.css + + Currenlty the xorg.css file is copied in each location + where a DocBook/XML file resides. This produces about + 70 copies in the $(docdir) install tree. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit fd5ef2fb841903c0a7d59e56f8fe69d0974f964c +Author: Jeremy Huddleston <jeremyhu@apple.com> +Date: Tue Nov 2 09:52:34 2010 -0700 + + xaw6.pc: Only list xmu in Requires.private, not Requires + + Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com> + + Based on earlier similar change to xaw7.pc which was: + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Tested-by: Gaetan Nadon <memsize@videotron.ca> + +commit 5136e2aabb73fec3c1670616bf0ebf828a1a1ca9 +Author: Cyril Brulebois <kibi@debian.org> +Date: Thu Oct 28 00:29:30 2010 +0200 + + Fix missing <X11/Intrinsic.h> in XawInit.h + + Configure scripts/test programs might have troubles detecting libXaw by + just including XawInit.h, since it doesn't include <X11/Intrinsic.h>, + even though it's needed for the Widget definition. + + X.Org Bugzilla #3526 <https://bugs.freedesktop.org/show_bug.cgi?id=3526> + + Signed-off-by: Cyril Brulebois <kibi@debian.org> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit 7b8196c9f7723b77b5d18fc1cc2070e557a7f767 +Author: Jeremy Huddleston <jeremyhu@apple.com> +Date: Mon Oct 25 12:33:32 2010 -0700 + + Move -I CFLAGS to CPPFLAGS + + Previously, setting CPPFLAGS at configure time could result in using the + installed headers rather than the ones included in the package. + + Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com> + +commit 46ca2da2e8d29d7f1347c9f4e9fb3794dd99cb7a +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Mon Oct 25 10:47:03 2010 -0700 + + libXaw 1.0.8 + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit b190356ebf2f0eb390ddf128edf1f0c761c3f14b +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sun Oct 24 22:38:05 2010 -0700 + + Add pointer to API spec in $(docdir) to Xaw.man + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Gaetan Nadon <memsize@videotron.ca> + +commit 35197044c7632b37322d15454589416fcdb7dc86 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sun Oct 24 22:28:42 2010 -0700 + + specs/Makefile.am: remove whitespace after line continuation chars + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit e20dbae7ab37431928e8f0f6d18644d0a7bdcdb7 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sun Oct 24 22:27:34 2010 -0700 + + Sun's copyrights now belong to Oracle + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit 47cab7a9160e4326107feac80ef4cc47289404ef +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Oct 17 20:29:02 2010 -0400 + + make: use MAN_SUBST now supplied in XORG_MANPAGE_SECTIONS + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 82f22390f2d1d78c9bc4f4900e3d088fd704eeb0 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Oct 17 20:26:32 2010 -0400 + + make: use the appropriate platform version of sed + + As provided by AC_PROG_SED now supplied by XORG_DEFAULT_OPTIONS + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit a2fa2705252db693d2b0f9da8f28fbfe3f88f083 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Oct 17 20:24:43 2010 -0400 + + config: use AC_PROG_INSTALL now supplied by XORG_DEFAULT_OPTIONS + + It depends on util-macros 1.8 or later + The existing statement can now be removed from the configuration file. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit b4d3a7153d9f39f9f385a750d39e30385caddd7e +Author: Jesse Adkins <jesserayadkins@gmail.com> +Date: Tue Sep 28 13:30:02 2010 -0700 + + Purge cvs tags. + + Signed-off-by: Jesse Adkins <jesserayadkins@gmail.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit f383e5989956dbaefc7bbacfe54bcc34e9144416 +Author: Walter Harms <wharms@bfs.de> +Date: Mon Aug 30 11:30:08 2010 -0400 + + Fix case statement typo in edit mode code + + Signed-off-by: Adam Jackson <ajax@redhat.com> + +commit b6750449f32c07fe277146b55a9f988bfaa3e0d2 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Aug 6 21:36:50 2010 -0700 + + xaw7.pc: Only list xmu in Requires.private, not Requires + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Tested-by: Gaetan Nadon <memsize@videotron.ca> + +commit fdeacea047db7c651f1640a6ade13063c29a816b +Author: Yaakov Selkowitz <yselkowitz@users.sourceforge.net> +Date: Sun Aug 8 22:05:45 2010 -0500 + + Remove symlinks created in install-exec-hook during uninstall + + Signed-off-by: Yaakov Selkowitz <yselkowitz@users.sourceforge.net> + Tested-by: Gaetan Nadon <memsize@videotron.ca> + +commit b8e3deb07d09f700026a37e4f887f20fae2bd93e +Author: Yaakov Selkowitz <yselkowitz@users.sourceforge.net> +Date: Sun Aug 8 05:19:12 2010 -0500 + + Install unversioned import library on Cygwin/MinGW + + Using LN_S is required for portability; on MinGW, this is "cp -p". + + The install-exec-hook in src/Makefile.am must remain !PLATFORM_WIN32, + as Windows cannot resolve DLL runtime dependencies from symlinks. + + Signed-off-by: Yaakov Selkowitz <yselkowitz@users.sourceforge.net> + Reviewed-by: Gaetan Nadon <memsize@videotron.ca> + +commit f7e3c7c8859cc25a1701507ed0f656cc38a2a550 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Tue Aug 3 15:23:57 2010 -0400 + + config: xorg-macros minimum of 1.10 required for XORG_CHECK_SGML_DOCTOOLS + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 95fe60384d60b31a33bec48a58242b8b5f2aa7a0 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sat Jul 24 11:03:56 2010 -0400 + + config: add AM_PROG_CC_C_O for per-target compilation flags + + Per-target compilation flags (libXaw7_la_CFLAGS) are required + when multiple targets which require different compiler flags, + are build in the same makefile. + + Automake issues a command with -c and -o flags which not all compilers + support. The object fles are prefixed with libXaw7_la. + The macro AM_PROG_CC_C_O must then be used to provide this feature + on compilers that do not have it. If not, a warning is issued at make time. + + This macros checks for compiler support and if missing, uses a "compile" + script it generates in the package root directory. + + Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit bd8cb49382a4277d6294a4fceda89b8d0769c5ba +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Fri Jul 9 20:42:16 2010 -0400 + + specs: use pattern rules rather than suffix rules + + This allows target to rebuild when included .xml files are changed. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 3191a58b3cd4c2ac3325bda0aa250f6cb973eac2 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Tue Jul 6 13:33:30 2010 -0400 + + specs: libXaw.xml was listed twice in dist_doc_DATA + + This should fix the dist/install target problem on some tinder boxes + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit e474cc545ed803012785029412e09ae09063ce39 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Tue Jul 6 13:09:24 2010 -0400 + + specs: remove file accidently checked-in + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 8d6114c248f7c8039a41dbc863240c63e3eccd54 +Author: Matt Dew <matt@osource.org> +Date: Tue Jul 6 09:06:52 2010 -0400 + + specs: replace troff source with docbook-xml source + + Placed specs files in the "specs" directory to be consistent + with other libraries specs. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit ad23722c4eec72f24d266291c31dfbed15d41e26 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Mon Mar 29 14:53:48 2010 -0400 + + config: remove the pkgconfig pc.in file from EXTRA_DIST + + Automake always includes it in the tarball. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit 0a86ae9ba2143642b29bc1c00a2f3f70eb5a1b52 +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Thu Jan 14 20:52:10 2010 -0800 + + Update Sun license notices to current X.Org standard form + + Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com> + +commit 7052118fed1c3734ac6d681130f62cd2899f9026 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Tue Feb 16 14:54:00 2010 -0500 + + spec: change install cmd due to automake 1.11 + + docData_INSTALL is defined in 1.9 and 1.10 but not 1.11 + + Reported-by: Tobias Droste <tdroste@gmx.de> + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit c690f3b7f85724eeb4e84c4f600a2408b00ee8af +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Tue Feb 9 17:46:41 2010 -0500 + + doc: use $(mkdir_p) rather than $(MKDIR_P) due to automake 1.9.6 + + $(MKDIR_P) is not defined in automake 1.9. + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit e87c5d8f8753a69f0b82c011c2b82bd53907bd4f +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Jan 31 18:30:58 2010 -0500 + + doc: use new macros to control doc generation + + Namely XORG_WITH_GROFF for the groff generation tool + XORG_ENABLE_SPECS for the generation of functional specs + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit db4fc91e01d51155322b8057b4dc60d56c3b26f2 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Sun Jan 31 17:43:29 2010 -0500 + + doc: clean-up generated html images + + Generate images in /images as is the convention + Provide a base file name for images rather than process ID + Remove images directory when running make clean + + Signed-off-by: Gaetan Nadon <memsize@videotron.ca> + +commit ceaf6f7f0e516b1479744df421de404b1decc556 +Author: Rémi Cardona <remi@gentoo.org> +Date: Thu Dec 17 08:28:30 2009 +0100 + + require autoconf 2.60 because of $(docdir) use + + Signed-off-by: Rémi Cardona <remi@gentoo.org> + Reviewed-by: Gaetan Nadon <memsize@videotron.ca> + Reviewed-by: Alan Coopersmith <alan.coopersmith@sun.com> + Reviewed-by: Dan Nicholson <dbn.lists@gmail.com> + +commit 4cf1bbc4a0f167eae794283f5d47be28192f6b14 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Fri Nov 27 20:56:03 2009 -0500 + + Makefile.am: add ChangeLog and INSTALL on MAINTAINERCLEANFILES + + Now that the INSTALL file is generated. + Allows running make maintainer-clean. + +commit 6509e9d695889f55f7749e10006aef7288e30cbd +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Wed Oct 28 15:24:48 2009 -0400 + + .gitignore: use common defaults with custom section # 24239 + + Add an ignore file for the new spec subdir + +commit ccf1bbf854152ed64e1f184388962361b7d828ae +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Wed Oct 28 15:19:25 2009 -0400 + + configure.ac: AM_MAINTAINER_MODE missing #24238 + + This turns off maintainer mode build rules in tarballs. + Works in conjunction with autogen.sh --enable-maintainer-mode + For all X.Org components. + +commit 504ec86f33975a1954136c875d09f7549557b962 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Wed Oct 28 14:09:10 2009 -0400 + + INSTALL, NEWS, README or AUTHORS files are missing/incorrect #24206 + + Add missing INSTALL file. Use standard GNU file on building tarball + README may have been updated + Remove AUTHORS file as it is empty and no content available yet. + Remove NEWS file as it is empty and no content available yet. + +commit b04ca66401a3ae83370c8b497561b099d45da246 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Mon Oct 26 22:08:42 2009 -0400 + + Makefile.am: ChangeLog not required: EXTRA_DIST or *CLEANFILES #24432 + + ChangeLog filename is known to Automake and requires no further + coding in the makefile. + +commit d56b65e53f5b7c4d1640ea5273827285f95f835c +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Thu Oct 22 16:19:19 2009 -0400 + + Makefile.am: do not include autogen.sh in distribution #24183 + + This is a private build script that should not be distributed + +commit b7a88244153030fc1e50be39edc81ce02e021f73 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Thu Oct 22 13:10:02 2009 -0400 + + .gitignore: use common defaults with custom section # 24239 + + Using common defaults will reduce errors and maintenance. + Only the very small or inexistent custom section need periodic maintenance + when the structure of the component changes. Do not edit defaults. + +commit 8a2925a69e6fc8627e7e92a9427e1885c3033ae7 +Author: Gaetan Nadon <memsize@videotron.ca> +Date: Thu Oct 22 12:34:19 2009 -0400 + + .gitignore: use common defaults with custom section # 24239 + + Using common defaults will reduce errors and maintenance. + Only the very small or inexistent custom section need periodic maintenance + when the structure of the component changes. Do not edit defaults. + +commit 2f64f87f34f79cbf8ef06d1399f9f4f26cce9e4c +Author: Julien Cristau <jcristau@debian.org> +Date: Wed Nov 25 16:06:06 2009 +0100 + + Remove Xaw8 copyright notices / license from COPYING + + All code carrying this notice has been removed already. + + Signed-off-by: Julien Cristau <jcristau@debian.org> + +commit cf01abd815c9dac9583eca383455448b72b435a1 +Author: Julien Cristau <jcristau@debian.org> +Date: Wed Nov 25 13:58:43 2009 +0100 + + Remove more Xaw8 remnants + + !defined(OLDXAW) && !defined(XAW7) was only true for Xaw8, as far as I + can tell. + The Print.h and PrintSP.h headers were already removed from the build + system, but remained in git unused. + + Signed-off-by: Julien Cristau <jcristau@debian.org> + Signed-off-by: Daniel Stone <daniel@fooishbar.org> + +commit f481179c69e991b9aa184399b9f1fffbcc2f999b +Author: Jeremy Huddleston <jeremyhu@freedesktop.org> +Date: Wed Oct 21 12:47:24 2009 -0700 + + This is not a GNU project, so declare it foreign. + + On Wed, 2009-10-21 at 13:36 +1000, Peter Hutterer wrote: + > On Tue, Oct 20, 2009 at 08:23:55PM -0700, Jeremy Huddleston wrote: + > > I noticed an INSTALL file in xlsclients and libXvMC today, and it + > > was quite annoying to work around since 'autoreconf -fvi' replaces + > > it and git wants to commit it. Should these files even be in git? + > > Can I nuke them for the betterment of humanity and since they get + > > created by autoreconf anyways? + > + > See https://bugs.freedesktop.org/show_bug.cgi?id=24206 + + As an interim measure, replace AM_INIT_AUTOMAKE([dist-bzip2]) with + AM_INIT_AUTOMAKE([foreign dist-bzip2]). This will prevent the generation + of the INSTALL file. It is also part of the 24206 solution. + + Signed-off-by: Jeremy Huddleston <jeremyhu@freedesktop.org> + +commit 51c3533c363f3224cbed37b3d8980bc8c1fa9ce1 +Author: Colin Harrison <colin.harrison@virgin.net> +Date: Tue Oct 20 17:34:19 2009 +0100 + + Lost parenthesis in a recent libXaw change + + Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com> + +commit f373e193a48eaf6d799d0b6ad32fd58d8ae8b3bd +Author: Eric Sesterhenn <eric.sesterhenn@lsexperts.de> +Date: Tue Oct 20 08:20:25 2009 -0700 + + Bug 24635: File Descriptor leaks in libxaw-1.0.7 + + http://bugs.freedesktop.org/show_bug.cgi?id=24635 + + Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com> + +commit 4ec346977273cc217b22a9225cb0d90351e6069c +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Sat Oct 17 14:45:39 2009 -0700 + + libXaw 1.0.7 + + Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com> + +commit d158018aad18552c5788df38de40ef50b7652dde +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Fri Oct 9 16:14:59 2009 -0700 + + Move Xaw specification document from xorg-docs module to spec/* + + Makefile support added to build postscript, text & html output, + and install it to ${docdir}, if groff is found and --disable-docs + was not specified + + Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com> + +commit b5a23647f0bbd68f226e7e03496144f838c09000 +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Fri Oct 9 11:02:07 2009 -0700 + + Migrate to xorg macros 1.3 & XORG_DEFAULT_OPTIONS + + Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com> + +commit b512bfc3fb5c489f4e1ef6529f7632bd70b9f461 +Author: Bernhard R. Link <brlink@debian.org> +Date: Fri Aug 18 16:29:10 2006 +0200 + + Xaw's tooltips remove timers not belonging to them + + Xaw's Tips.c registers and releases timers for tooltips to show, + but does not remember a timer already triggered. Thus it releases + timers no longer belonging to it but to other users of Xt Timeouts + within the same program. (This even happens very often, as Xt reuses + old TimeEventRecs, so the next one adding a timeout will get exactly + this number.) + + Section 7.1.3 of Intrinsic.txt.gz says: + + | Note that timeouts are automatically removed once they trig- + | ger. + + src/Repeater.c correctly forgets the timer when it is triggered, but + src/StripChart.c does very strange things with Xt Timeouts, which + very likely will have similar problems. + + X.Org bug#9936 <http://bugs.freedesktop.org/show_bug.cgi?id=9936> + +commit 2ef9c2d730200246405cfdfc882a66fbd6728a92 +Author: Adam Jackson <ajax@redhat.com> +Date: Thu Jul 2 13:37:13 2009 -0400 + + libXaw 1.0.6 + +commit 9d9facf604d2355842a3834664a1ddc233d4d1e1 +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Mon Feb 2 20:34:32 2009 -0800 + + Add README with pointers to mailing list, bugzilla & git repos + + Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com> + +commit 654fd414b7ebe3a0fccd6712bf52666d42d2a711 +Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> +Date: Fri Jan 9 20:24:10 2009 -0200 + + Changed AsciiSrc widget to use only binary selection transfers. + + Conversion from multi byte to single byte text format, and + vice versa, frequently doesn't do what the user want, so, + operate only on literal/binary selection transfers. + +commit 0b9de9e69e95872dd3eddbe5c1602e42c27c53e1 +Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> +Date: Fri Jan 9 19:18:36 2009 -0200 + + Compile warning fixes. + + This uses XORG_CHANGELOG macro to properly work with the "git-log" + to "git log" change (required to pass "make distcheck"), uses the + XORG_CWARNFLAGS macro. Most gcc 4.3 and sparse warnings corrected. + +commit 420efdba52593bf13d97c7e001b64caccd04cd5d +Author: Jeremy Huddleston <jeremyhu@freedesktop.org> +Date: Sat Nov 8 16:04:23 2008 -0800 + + Fixed compile/install on darwin + +commit a48021b05693c74bd03b51b82abec4ce3ba24dc5 +Author: Peter Breitenlohner <peb@mppmu.mpg.de> +Date: Sat Nov 8 15:44:22 2008 +0100 + + xaw6 doesn't depend on xpm + +commit 6dab13545cd26efd46dbb58a18ae651c56c7d76d +Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> +Date: Fri Nov 7 15:45:32 2008 -0200 + + libXaw version 1.0.5. + +commit 90a343b898dabb8cac5ec831b45e20b1abd306ac +Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> +Date: Fri Nov 7 15:36:15 2008 -0200 + + Correct build on systems that did not yet upgrade to libtool-2.2 + + Also correct lib Changelog generation by running "git log" instead of + "git-log", what should work on all versions of git. + The libtool correction issue is probably a hack over several other + hacks. The proper correction should be to ensure that AC_PROG_SED is run + before the AC_CONFIG_COMMANDS([libtool_hack],...), what appears to be the + case in latest libtool, but not 1.5.x. + +commit 8256de6062eb150c612ef09a1ae855de0a0cba6c +Author: Lee Leahu <freedesktop-bugs@dyweni.com> +Date: Fri Nov 7 11:00:15 2008 -0500 + + Fix configure error when using libtool-2.2.* + + The configure script errors out when preparing to compile libXaw. + + The error occurs with libtool-2.2.6a and libtool-2.2.4. + + The error does not occur with libtool-1.5.26. + + The error is caused because the libtool file is not created by the + time sed attempts to fix the SONAME. + + Libtool-2.2 made an incompatible change to LT_INIT (which replaces + AC_PROG_LIBTOOL): it generates the libtool script at the AC_OUTPUT, + rather then right after being called. Sometimes, configure scripts + call configure to run tests or read its settings; in those cases, + LT_OUTPUT can be appended to force libtool generation earlier. + + There is one caveat: libtool is still (re)generated during AC_OUTPUT, + so in our case, even adding LT_OUTPUT wouldn't help, because the sed + changes are overwritten. + + AFAICS the solution is to use AC_CONFIG_COMMANDS; patch against + current git master attached. + + Report and patch from: http://bugs.freedesktop.org/show_bug.cgi?id=18073 + + Signed-off-by: James Cloos <cloos@jhcloos.com> + +commit 012e73faab8dc8617c6da4679715dae14f6cddd4 +Author: Daniel Stone <daniel@fooishbar.org> +Date: Fri Aug 15 18:25:53 2008 +0300 + + Remove last remaining vestiges of Xprint support + + Occasionally I think I'm smart enough to commit without testing, then I + break the build. Bad Daniel. No biscuit. + +commit 3cbe136d633d18b263f596638d55f8f13fabd540 +Author: Daniel Stone <daniel@fooishbar.org> +Date: Fri Aug 15 17:59:59 2008 +0300 + + Remove Xaw8 (Xprint) + + Remove Xaw8, which only provided Xprint support over Xaw7. + +commit 89416252097c97833c879dc2be56d2b6cd6a8f88 +Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> +Date: Wed Jul 23 18:08:09 2008 -0300 + + Minor set of trivial corrections. + + Ansify two non ansified functions definitions. + Don't declare a variable that is not used. + Actually declare the prototype a function that is defined unconditionally. + +commit 43cb3d388eae5a814ac4f36edca5780a6ea4934f +Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> +Date: Fri Jul 11 17:21:18 2008 -0300 + + Remove almost 10 year old notice about Xaw development from man page. + + Correct a problem when deleting text portions that may lead to a crash + due to accessing released memory; in most cases it would crash in + AsciiSink.c:AsciiPreparePaint() when calling XtMalloc() with a negative + value. + The problem was due to not properly removing/updating XawTextEntity + objects. One case that can cause the problem to happen is with patch files + with syntax highlight, and sequentially selecting a deleting them. At one + point attempt to remove the "first" XawTextAnchor, and also incorrectly + update it's offset value to a negative value. The problem is not easy + to reproduce as it requires a file with a special pattern (in this case + the syntax highlight used for patch) and it would fail after removing + all "entities" of the second "anchor". + +commit 0b6058db1ce978f17d6eb99f5b253b813a133294 +Author: Dan Nicholson <dbn.lists@gmail.com> +Date: Thu Jul 10 16:21:06 2008 -0700 + + Use sed instead of ed for libtool SONAME hacking + + Since sed is already required by autoconf and libtool, it makes sense to + use it instead of pulling in ed, too. The editing script only has to be + changed slightly to accommodate this. The resulting libtool has been + checked to be the same on Linux (GNU sed) and HP-UX. + + Building libXaw was the only reason I have ed on my system anymore. + Maybe someday this can be fixed properly. + +commit b605a26ff481259d4aca466ae68142f53ced43ce +Author: Dan Nicholson <dbn.lists@gmail.com> +Date: Thu Jul 10 15:37:51 2008 -0700 + + Be more robust using ed for the libtool hacks + + Two failures during the libtool SONAME hacking that were being ignored + are now fixed: + * ed was called without first checking that it exists + * ed could fail in editing the libtool script + +commit fa7dd561c40ce3dcd8252b5eda09258836659d66 +Author: Colin Harrison <colin.harrison-at-virgin.net> +Date: Wed Apr 23 10:18:15 2008 +0100 + + Add MINGW32 definition + +commit 8c0f99b1d1f0d5d3b734a43eddb10bd8c5397aed +Author: Matthieu Herrb <matthieu.herrb@laas.fr> +Date: Sun Mar 9 00:24:33 2008 +0100 + + Makefile.am: nuke RCS Id + +commit 857781383ef123a31a84a766507a8e11b9e3f778 +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Tue Aug 21 13:19:01 2007 -0700 + + Version bump: 1.0.4 + +commit cf90924541fe9af09c582ddd60953c4a08ceb004 +Author: Eric S. Raymond <esr@thyrsus.com> +Date: Sun Jan 14 10:34:00 2007 -0800 + + Bug #9649: Bad markup on XAw.3x + + X.Org Bugzilla #9649 <https://bugs.freedesktop.org/show_bug.cgi?id=9649> + +commit 0515e29cfc0ed99b06dcf9399a0504bde7c81d93 +Author: Daniel Drake <ddrake@brontes3d.com> +Date: Tue May 29 12:21:00 2007 -0800 + + Bug #11091: libXaw COPYING file + + X.Org Bugzilla #11091 <https://bugs.freedesktop.org/show_bug.cgi?id=11091> + Attachment #10122 <https://bugs.freedesktop.org/attachment.cgi?id=10122> + +commit ee6e61225943ec77c8b97ae8115ce37c42e8c16e +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Wed Apr 11 20:15:00 2007 -0700 + + Use iswalnum() if it's present as a function, not just if it's #defined + + Also fixes X.Org bugzilla #8564 + +commit eccdec2bf4680b42036f03a7ce0ae9bfe5ef5374 +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Wed Jan 3 21:30:22 2007 -0800 + + Version bump: 1.0.3 + +commit a2d3487dd5422ef273acae83cc20078a1a9f37c6 +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Wed Jan 3 21:19:37 2007 -0800 + + Replace static ChangeLog with dist-hook to generate from git log + +commit c653eb5742b0ef50570a8371d7787eeb1e7b5667 +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Wed Jan 3 21:12:07 2007 -0800 + + Add call to PKG_PROG_PKG_CONFIG so configure doesn't break with --disable-xaw6 + +commit 32d0891b982b4cea322bdc2d8ecd32e912c70f54 +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Wed Jan 3 21:09:36 2007 -0800 + + Add *~ to .gitignore to skip over patch/emacs droppings + +commit 21a1c92130ef304607b696c8e5db2185a89a4ba7 +Author: Alan Coopersmith <alan.coopersmith@sun.com> +Date: Thu Jul 13 14:58:49 2006 -0700 + + renamed: .cvsignore -> .gitignore + +commit e487a686b1e251936c0926ff124c1b754814c7f5 +Author: Adam Jackson <ajax@nwnk.net> +Date: Thu Apr 27 00:03:33 2006 +0000 + + Bump to 1.0.2 + +commit 580c3f12423e15192f4eff456ebf2f6246318bd9 +Author: Adam Jackson <ajax@nwnk.net> +Date: Mon Apr 3 19:23:16 2006 +0000 + + Bug #6404: Cygwin build fixes (Yaakov Selkowitz) + +commit 735d010ee2c6dc2a6279dc16d1c9a1128c59d91a +Author: Kevin E Martin <kem@kem.org> +Date: Wed Dec 21 02:30:05 2005 +0000 + + Update package version for X11R7 release. + +commit 3b81b8af98277206eea791f0f9e7cf5a617a4b20 +Author: Adam Jackson <ajax@nwnk.net> +Date: Mon Dec 19 16:28:26 2005 +0000 + + Stub COPYING files + +commit 7f10a61e2cb38bbfee07fed4596ae176be3b7bb4 +Author: Kevin E Martin <kem@kem.org> +Date: Thu Dec 15 00:24:28 2005 +0000 + + Update package version number for final X11R7 release candidate. + +commit 12566cf69c51989ee932e812db0f2186c64b540b +Author: Kevin E Martin <kem@kem.org> +Date: Thu Dec 8 17:55:18 2005 +0000 + + Add configure options to allow hard-coded paths to be changed. + +commit a108ef7e6a7864179bdf16b3adf08428dd66f4ad +Author: Kevin E Martin <kem@kem.org> +Date: Tue Dec 6 22:48:42 2005 +0000 + + Change *man_SOURCES ==> *man_PRE to fix autotools warnings. + +commit 570029e344a36d8d0bcab5b2ea5b4f87ea508535 +Author: Kevin E Martin <kem@kem.org> +Date: Mon Dec 5 17:48:19 2005 +0000 + + Fix libtool hack to work with older libtools. + +commit 28645b0df40bcd428d98eb18aeb8d0875f12f4e3 +Author: Kevin E Martin <kem@kem.org> +Date: Sat Dec 3 05:49:42 2005 +0000 + + Update package version number for X11R7 RC3 release. + +commit 80a520a1a1724e0ba00c94139ca871f1944b4be1 +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Mon Nov 28 22:03:05 2005 +0000 + + Change *mandir targets to use new *_MAN_DIR variables set by xorg-macros.m4 + update to fix bug #5167 (Linux prefers *.1x man pages in man1 subdir) + +commit 651a3e0a2dcead0aad75734b438bf900de4f7c5c +Author: Kevin E Martin <kem@kem.org> +Date: Sun Nov 27 16:44:43 2005 +0000 + + Fix Xaw6 to build without Xpm. + +commit 1c36da4ef2e308cb5b7a80b1e914fd637d622fae +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Mon Nov 21 03:24:10 2005 +0000 + + libXaw6 shouldn't depend on libXpm, only Xaw7 & Xaw8 should + +commit 7cec5bf0ee960356821bea08a30feb92dcbf186e +Author: Kevin E Martin <kem@kem.org> +Date: Sat Nov 19 07:15:40 2005 +0000 + + Update pkgconfig files to separate library build-time dependencies from + application build-time dependencies, and update package deps to work + with separate build roots. + +commit cb243066d12834c2f63a82f9695761a01400e26f +Author: Kevin E Martin <kem@kem.org> +Date: Wed Nov 9 21:19:12 2005 +0000 + + Update package version number for X11R7 RC2 release. + +commit db01f1c4c84768e818dbfa28556f246b91c1391d +Author: Kean Johnson <kean@armory.com> +Date: Tue Nov 8 06:33:25 2005 +0000 + + See ChangeLog entry 2005-11-07 for details. + +commit ca1c1425e53143899f212c6e783eec1eeb59e481 +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Fri Oct 28 17:28:50 2005 +0000 + + Add libXaw.so.N -> libXawN.so.N links for platforms where ldconfig doesn't + add them automatically for you. + +commit 6f7e7194574ef1bed6ba7db4304d9e064c4f24c7 +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Mon Oct 24 17:33:04 2005 +0000 + + Add -DOLDXAW to flags for building libXaw6 to disable features that are + only supposed to be in the newer versions. + +commit 7801c38f76000d4b93cc2208ad80e04505c6ff85 +Author: Adam Jackson <ajax@nwnk.net> +Date: Sun Oct 23 00:50:43 2005 +0000 + + Add xext check + +commit 8c7f3e277321213fc2798a73a88e222f145c3b59 +Author: Kevin E Martin <kem@kem.org> +Date: Wed Oct 19 02:48:09 2005 +0000 + + Update package version number for RC1 release. + +commit 4836a84ebcc266c35be110c7f708d0b221360e91 +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Tue Oct 18 00:00:08 2005 +0000 + + Use @LIB_MAN_SUFFIX@ instead of $(LIB_MAN_SUFFIX) in macro substitutions to + work better with BSD make + +commit 0f4847e12e3a3b7ce3cbfaaf282a92e3f1be2073 +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Thu Oct 13 04:26:32 2005 +0000 + + Missed changelog + +commit ec0fdd5646ab4f4642a73860b24a155560c94616 +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Thu Oct 13 04:25:46 2005 +0000 + + Add generated man pages to .cvsignores + +commit 7b0d5f78d4e853014b6110066208ba237bd8c2a3 +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Thu Oct 13 04:07:32 2005 +0000 + + Use sed to fill in variables in man page + +commit 2692d1b40d46d3d97526664c2bc0130eb1900197 +Author: Kevin E Martin <kem@kem.org> +Date: Wed Oct 5 21:34:53 2005 +0000 + + Add old-doc files to EXTRA_DIST + Add Template.c to install list + Add sharedlib.c to EXTRA_DIST + Remove the unneeded Makefile.am's + +commit bb18f5fb61626da0a5422a36830e57cd070981c2 +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Sat Jul 30 19:53:03 2005 +0000 + + Check for headers used by XawI18N.h and define the needed HAS_*_H symbols. + +commit 223c18dd13a524d144b856118b6f2ec036ae106d +Author: Kevin E Martin <kem@kem.org> +Date: Fri Jul 29 21:22:50 2005 +0000 + + Various changes preparing packages for RC0: + - Verify and update package version numbers as needed + - Implement versioning scheme + - Change bug address to point to bugzilla bug entry form + - Disable loadable i18n in libX11 by default (use --enable-loadable-i18n to + reenable it) + - Fix makedepend to use pkgconfig and pass distcheck + - Update build script to build macros first + - Update modular Xorg version + +commit 3ce58da9ecd5337738b8b35cdeaab64b32b521cd +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Wed Jul 27 23:59:16 2005 +0000 + + Set build_v8=yes when using autodetection to decide whether or not to build + Xaw8 and libXp is found, so that it actually is built. + +commit b4e81526a0013ebdc8aa8c0dfb427db850213a7b +Author: Daniel Stone <daniel@fooishbar.org> +Date: Fri Jul 22 07:19:44 2005 +0000 + + Fix autodetection of Xprint and quote arguments properly. + +commit e4ea145e991e947483054d85412002e64aeb08ea +Author: Daniel Stone <daniel@fooishbar.org> +Date: Sat Jul 16 06:30:43 2005 +0000 + + Set version numbers to 6.1.0, 7.0.0 and 8.0.0 with -version-number. + +commit cf08b572fb22334e29ec56930f3cecba1dc18629 +Author: Adam Jackson <ajax@nwnk.net> +Date: Thu Jul 14 05:56:32 2005 +0000 + + style fix. don't use +=, just do conditionally defined variables. fixes + build on a particularly picky platform. + +commit 3608270b1d1685082d9dab401d0e7d1aa9c91ba8 +Author: Alan Coopersmith <Alan.Coopersmith@sun.com> +Date: Sun Jul 10 19:53:50 2005 +0000 + + grep -q is sadly not universally supported, use grep > /dev/null instead + +commit c22f98ed4fae3ccde3ff9a272b019a67fbc78c55 +Author: Keith Packard <keithp@keithp.com> +Date: Sat Jul 9 06:11:58 2005 +0000 + + Add .cvsignore files + Build all three versions in src. Hack libtool to set SONAME in the libtool + output to match old libXaw file names. Still missing is the creation of + appropriate symlinks from libXaw.so.6 -> libXaw6.so.6 et al so that + libraries not yet installed will work properly. + +commit 5fc8851308321a65a6987aedea6618d056ff7879 +Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk> +Date: Wed Jul 6 19:26:27 2005 +0000 + + - Xaw/xaw.m4: Change help string to say "enable xprint" instead of "disable + xprint" + - symlink.sh: Rename Bitmap-co.ad to Bitmap-color.ad. Add bitmaps for the + bitmap application. Add xdbedizzy.sgml. + - xc/programs/xdbedizzy/: Conditionalize use of xprint + - remove font/arabic-misc/README and font/mutt-misc/README + +commit d4f214b6255184a2cbf571c02409a0e3f4405fb0 +Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk> +Date: Tue Jul 5 22:51:11 2005 +0000 + + Add build systems for xlogo, xlsatoms, xlsclients, xmag, xman, xmessage, + xmh, xmore. lib/Xaw/xaw.m4: Add an AM_CONDITIONAL and a shell variable + xaw_use_xprint symlink.sh: add some extra files for xgc, xinit, + xkbcomp, xlogo, xmb, and xmodmap xc/programs/xmore/xmore.c: + Conditionalize use of xprint + +commit 0e08a2ffb4b063b96d25dd7490caf91cb5bb6126 +Author: Daniel Stone <daniel@fooishbar.org> +Date: Sun Jul 3 07:00:56 2005 +0000 + + Add Xtrans definitions (FONT_t, TRANS_CLIENT) to clean up warnings. + Add XSERV_t, TRANS_SERVER, TRANS_REOPEN to quash warnings. + Add #include <dix-config.h> or <xorg-config.h>, as appropriate, to all + source files in the xserver/xorg tree, predicated on defines of + HAVE_{DIX,XORG}_CONFIG_H. Change all Xfont includes to + <X11/fonts/foo.h>. + +commit f8e7a4ec6117006123dfdc7c970f9f1392bf7d84 +Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk> +Date: Tue Jun 28 13:30:15 2005 +0000 + + lib/Xaw/Makefile.am: install the libXaw.so symlink in $(DESTDIR)$(libdir) - + pointed out by Stefan Dirsch + lib/Xaw/man/Makefile.am: add Xaw.man to EXTRA_DIST to make it distcheck. + +commit c35ec1561bfc9bf8d79b68a071619f4904764002 +Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk> +Date: Mon Jun 27 21:35:04 2005 +0000 + + - Fix string test in lib/Xaw/xaw.m4 + - Xaw/Xaw7/Makefile.am: add -DXAW7 + - add build system for editres + +commit f6c298f70e13ecf37b4824f6ac01007b876dd3cb +Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk> +Date: Fri Jun 24 22:54:24 2005 +0000 + + Add m4 macro to check for versions of the Xaw library + +commit e3e78cd7815716d8af729c19833bec51d7e3f19c +Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk> +Date: Fri Jun 24 21:20:32 2005 +0000 + + Change the so names to libXaw{6,7,8}.so and install a symlink from + libXaw.so to the newest version installed + +commit cc658b573a13f36868c5a2263e0b3ff8d0230b86 +Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk> +Date: Mon May 23 21:47:37 2005 +0000 + + Conditionally include config.h in xc/lib/Xaw/*.c + +commit 62b680d868fbe4bfdf1af6e6067d0ef27f773559 +Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk> +Date: Mon May 23 20:01:46 2005 +0000 + + Check in build system for Xaw + +commit f9faf0399180abbc89e44d5077b9070294c2f507 +Author: Egbert Eich <eich@suse.de> +Date: Thu Jan 27 10:22:11 2005 +0000 + + Muffle gcc4 sentinel (trailing NULL in varargs list) check (Marcus + Meissner, Bugzilla #2392). + +commit 33f42c97af49095dd9a735c747c79b844e6afc25 +Author: Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> +Date: Sat Dec 4 00:42:47 2004 +0000 + + Encoding of numerous files changed to UTF-8 + +commit 4904540c4399fed01ce0d1977a0b5d3af173b66c +Author: Egbert Eich <eich@suse.de> +Date: Tue Sep 21 17:57:36 2004 +0000 + + Merged over libXpm security fix provided by Chris Evans, Matthieu Herrb and + Alan Coopersmith from release 6.8.1. + Fail during initialization with error if font/fontset is not set for + widget. This prevents a sig11 later when the non-existent font/fontset + structs are referenced. + Check if xf86Info.kbdProc pointer is really set before calling it on abort + as this pointer won't be set if the new modular keyboard driver is used + (Matthias Hopf). + Added new libs to the bindist control files. + Removed inclusion of unnecessary kernel header on Linux. This may fail in + an -ansi environment. + +commit c7f720ae3f0dea94bc6e9eb9bdbbf00e6bb16b24 +Author: Kevin E Martin <kem@kem.org> +Date: Thu Sep 2 01:10:29 2004 +0000 + + Bump major version number of libXaw (Bug #1273). + +commit 93df4ff66635ea936d57723d317d0a0cdaa55e62 +Author: Kristian Høgsberg <krh@redhat.com> +Date: Mon Aug 16 16:36:14 2004 +0000 + + As discussed and agreed on on the release-wranglers meeting of August 16, + I'm committing the patch from bug #1060 to back out unconditional + Xprint functionality. + Back out Xprint changes. + Revert xman to CVS of June 5, revert xlogo to CVS of May 8, revert xedit to + CVS of April 25, to back out unconditional Xprint support. + Fix up Xprint config logic to be like the rest of the extensions: + BuildXprint is a one-stop option for disabling everything Xprint + related. XprtServer controls building Xprt, BuildXprintLib controls + building Xprint libs and BuildXprintClients controls building clients + related to Xprint. BuiltXprint defaults to YES and the other options + respects relevant settings, i.e. BuildServer and BuildServersOnly. + Build Xaw regardless of BuildXprintLib setting. + Only build xphelloworld, xplsprinters and xprehashprinterlist when + BuildXprintClients it YES. Disable building xmore, it has always + supported XawPrintShell. + Make Xprint support depend on BuildXprintLib. + +commit c0753d383d2b610863873fda5a1d2c65674e37b0 +Author: Roland Mainz <roland.mainz@nrubsig.org> +Date: Thu Jul 29 00:40:34 2004 +0000 + + Fix for https://freedesktop.org/bugzilla/show_bug.cgi?id=938 - Update + XawPrintShell per feedback and review comments. + +commit 021dac1e5b9394a228dfe69f10307a2596c48135 +Author: Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de> +Date: Tue Jun 29 15:53:10 2004 +0000 + + #Bug 806: undefined reference to xawPrintShellWidgetClass in Xaw6 for + cygwin. Wrap references to xawPrintShellWidgetClass with #ifndef + OLDXAW. + +commit fcb62987b01b7166a4b1aceb677a2a777e6ba482 +Author: Egbert Eich <eich@suse.de> +Date: Thu May 6 17:31:17 2004 +0000 + + BugZilla #601: Fixing makedepend choking on floating point exception + because CHAR_BIT is defined to __CHAR_BIT__ which is a compiler + intrinsic define. BugZilla #605: Fixing build on IA64 which is broken + due to the inclusion of the kernel header asm/page.h. Kernel headers + however don't work with + -ansi. The inclusion of asm/page.h can however savely be removed as it + there are plenty of other ways to determine the page size. + +commit 39c07a5fa73bcbb48d5de8985d5f2540b65e470b +Author: Egbert Eich <eich@suse.de> +Date: Fri Apr 23 18:43:38 2004 +0000 + + Merging XORG-CURRENT into trunk + +commit 5aa2c5d2169757ae410f1d13c5279fd4030b72f0 +Author: Roland Mainz <roland.mainz@nrubsig.org> +Date: Tue Apr 13 23:32:21 2004 +0000 + + file PrintShell.c was initially added on branch XPRINT. + +commit 31c961a93829b50fa0694a431fd1574cc2c67ea2 +Author: Roland Mainz <roland.mainz@nrubsig.org> +Date: Tue Apr 13 23:32:21 2004 +0000 + + file PrintSP.h was initially added on branch XPRINT. + +commit 04af3b0444e8514173c44fac44864f15119f93b4 +Author: Roland Mainz <roland.mainz@nrubsig.org> +Date: Tue Apr 13 23:32:21 2004 +0000 + + file Print.h was initially added on branch XPRINT. + +commit f601320d34173365050a04d8f1ec661ee1f541dd +Author: Egbert Eich <eich@suse.de> +Date: Sun Mar 14 08:32:04 2004 +0000 + + Importing vendor version xf86-4_4_99_1 on Sun Mar 14 00:26:39 PST 2004 + +commit d01cf1b69fd5444606b9183db6114a2972dcba0c +Author: Egbert Eich <eich@suse.de> +Date: Wed Mar 3 12:11:23 2004 +0000 + + Importing vendor version xf86-4_4_0 on Wed Mar 3 04:09:24 PST 2004 + +commit 0f9ae1ce47cc2271cb61887136c9a6b56b9ec4ba +Author: Egbert Eich <eich@suse.de> +Date: Thu Feb 26 13:35:32 2004 +0000 + + readding XFree86's cvs IDs + +commit 0011f36c334046cce1126d4e3b45fead8fac551c +Author: Egbert Eich <eich@suse.de> +Date: Thu Feb 26 09:22:42 2004 +0000 + + Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004 + +commit c75f90ead1132640b2848babda6625c800528a8c +Author: Egbert Eich <eich@suse.de> +Date: Thu Jan 29 08:08:05 2004 +0000 + + Importing vendor version xf86-012804-2330 on Thu Jan 29 00:06:33 PST 2004 + +commit 04a6533a94a1e0800c1806617b6dda48f30f9e6f +Author: Kaleb Keithley <kaleb@freedesktop.org> +Date: Fri Dec 19 20:54:35 2003 +0000 + + XFree86 4.3.99.902 (RC 2) + +commit ffc55826a7c787dd65d3dd577fa0ac7a111540e3 +Author: Kaleb Keithley <kaleb@freedesktop.org> +Date: Tue Nov 25 19:28:09 2003 +0000 + + XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folks + +commit 384ac455a6cd5d23dfa24f9939f3ec04f1e5de46 +Author: Kaleb Keithley <kaleb@freedesktop.org> +Date: Fri Nov 14 16:48:48 2003 +0000 + + XFree86 4.3.0.1 + +commit 81ad93fde745d556aaa3880deabf3674bb3db49e +Author: Kaleb Keithley <kaleb@freedesktop.org> +Date: Fri Nov 14 16:48:48 2003 +0000 + + Initial revision + +commit b6e0280a57c4dfa572770241a42fe6a476109516 +Author: Kaleb Keithley <kaleb@freedesktop.org> +Date: Fri Nov 14 15:54:38 2003 +0000 + + R6.6 is the Xorg base-line diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..8b82ade --- /dev/null +++ b/INSTALL @@ -0,0 +1,291 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008 Free Software Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 6. Often, you can also type `make uninstall' to remove the installed + files again. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `<wchar.h>' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *Note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..d8869f0 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,49 @@ +SUBDIRS = include src man specs + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = + +if BUILD_XAW6 + +pkgconfig_DATA += xaw6.pc +if PLATFORM_DARWIN +DEFAULT_LIB = libXaw.6.@LIBEXT@ +else +DEFAULT_LIB = libXaw6.@LIBEXT@ +endif + +endif + +if BUILD_XAW7 + +pkgconfig_DATA += xaw7.pc +if PLATFORM_DARWIN +DEFAULT_LIB = libXaw.7.@LIBEXT@ +else +DEFAULT_LIB = libXaw7.@LIBEXT@ +endif + +endif + +MAINTAINERCLEANFILES = ChangeLog INSTALL +EXTRA_DIST = \ + autogen.sh \ + old-doc/Changelog \ + old-doc/CHANGES + +install-exec-hook: + cd $(DESTDIR)$(libdir) && rm -f libXaw.@LIBEXT@ && $(LN_S) $(DEFAULT_LIB) libXaw.@LIBEXT@ + +uninstall-local: + -rm -f $(DESTDIR)$(libdir)/libXaw.@LIBEXT@ + + +.PHONY: ChangeLog INSTALL + +INSTALL: + $(INSTALL_CMD) + +ChangeLog: + $(CHANGELOG_CMD) + +dist-hook: ChangeLog INSTALL diff --git a/README b/README new file mode 100644 index 0000000..14aa939 --- /dev/null +++ b/README @@ -0,0 +1,26 @@ +Xaw is the X Athena Widget Set. +Xaw is a widget set based on the X Toolkit Intrinsics (Xt) Library. + +All questions regarding this software should be directed at the +Xorg mailing list: + + http://lists.freedesktop.org/mailman/listinfo/xorg + +Please submit bug reports to the Xorg bugzilla: + + https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +The master development code repository can be found at: + + git://anongit.freedesktop.org/git/xorg/lib/libXaw + + http://cgit.freedesktop.org/xorg/lib/libXaw + +For patch submission instructions, see: + + http://www.x.org/wiki/Development/Documentation/SubmittingPatches + +For more information on the git code manager, see: + + http://wiki.x.org/wiki/GitPage + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..904cd67 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" diff --git a/compile b/compile new file mode 100755 index 0000000..bac481c --- /dev/null +++ b/compile @@ -0,0 +1,310 @@ +#! /bin/sh +# Wrapper for compilers which do not understand `-c -o'. + +scriptversion=2010-11-15.09; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010 Free Software +# Foundation, Inc. +# Written by Tom Tromey <tromey@cygnus.com>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, 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 <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Win32 hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l*) + lib=${1#-l} + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + set x "$@" "$dir/$lib.dll.lib" + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + set x "$@" "$dir/$lib.lib" + break + fi + done + IFS=$save_IFS + + test "$found" != yes && set x "$@" "$lib.lib" + shift + ;; + -L*) + func_file_conv "${1#-L}" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand `-c -o'. +Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file `INSTALL'. + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we strip `-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..3ed625e --- /dev/null +++ b/configure.ac @@ -0,0 +1,115 @@ + +# Initialize Autoconf +AC_PREREQ([2.60]) +AC_INIT([libXaw], [1.0.11], + [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXaw]) +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_HEADERS([config.h]) + +# Initialize Automake +AM_INIT_AUTOMAKE([foreign dist-bzip2]) +AM_MAINTAINER_MODE + +# Initialize libtool +AC_PROG_LIBTOOL + +# Require xorg-macros minimum of 1.12 for DocBook external references +m4_ifndef([XORG_MACROS_VERSION], + [m4_fatal([must install xorg-macros 1.12 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.12) +XORG_DEFAULT_OPTIONS +XORG_ENABLE_SPECS +XORG_WITH_XMLTO(0.0.22) +XORG_WITH_FOP +XORG_WITH_XSLTPROC +XORG_CHECK_SGML_DOCTOOLS(1.8) + +# Some compilers do not support per target -c and -o flags +AM_PROG_CC_C_O + +# Checks for programs. +AC_PROG_AWK + +# Need to call this explicitly since the first call to PKG_CHECK_MODULES +# is in an if statement, and later calls would break if it's skipped. +PKG_PROG_PKG_CONFIG + +# +# fix libtool to set SONAME to libXaw.so.$major +# +AC_CONFIG_COMMANDS([libtool_hack], [ + cp -f libtool libtool_ + test -z "$SED" && SED=sed + $SED '1,/^soname_spec/{ +/^soname_spec/i\ +# X.Org hack to match monolithic Xaw SONAME\ +xorglibxawname="libXaw" +/^soname_spec/s/libname/xorglibxawname/ +}' libtool_ > libtool + rm -f libtool_ +]) + +# OSX/Win32 rules are different. +platform_win32=no +platform_darwin=no +LIBEXT=so +case $host_os in + cygwin*|mingw*) + LIBEXT=dll.a + platform_win32=yes + ;; + darwin*) + LIBEXT=dylib + platform_darwin=yes + ;; +esac +AC_SUBST(LIBEXT) +AM_CONDITIONAL(PLATFORM_WIN32, test "x$platform_win32" = "xyes") +AM_CONDITIONAL(PLATFORM_DARWIN, test "x$platform_darwin" = "xyes") + +# Whether to build Xaw6 + +AC_ARG_ENABLE(xaw6, AS_HELP_STRING([--disable-xaw6], + [Disable building of libXaw.so.6]), + [build_v6=$enableval], [build_v6=yes]) + +if test "x$build_v6" = xyes; then + PKG_CHECK_MODULES(XAW6, xproto x11 xext xextproto xt xmu) +fi + + +# Whether to build Xaw7 + +AC_ARG_ENABLE(xaw7, AS_HELP_STRING([--disable-xaw7], + [Disable building of libXaw.so.7]), + [build_v7=$enableval], [build_v7=yes]) + +if test "x$build_v7" = xyes; then + PKG_CHECK_MODULES(XAW7, xproto x11 xext xextproto xt xmu xpm) +fi + + +AM_CONDITIONAL(BUILD_XAW6, [test x$build_v6 = xyes]) +AM_CONDITIONAL(BUILD_XAW7, [test x$build_v7 = xyes]) + +# Checks for header files. +AC_CHECK_HEADERS([wctype.h wchar.h widec.h]) + +# Checks for functions +AC_CHECK_FUNCS([iswalnum getpagesize]) + +AC_CONFIG_FILES([Makefile + include/Makefile + man/Makefile + specs/Makefile + src/Makefile]) + +if test "x$build_v6" = xyes; then + AC_CONFIG_FILES(xaw6.pc) +fi + +if test "x$build_v7" = xyes; then + AC_CONFIG_FILES(xaw7.pc) +fi + +AC_OUTPUT diff --git a/docbook.am b/docbook.am new file mode 100644 index 0000000..bba4d54 --- /dev/null +++ b/docbook.am @@ -0,0 +1,105 @@ +# +# Generate output formats for a single DocBook/XML with/without chapters +# +# Variables set by the calling Makefile: +# shelfdir: the location where the docs/specs are installed. Typically $(docdir) +# docbook: the main DocBook/XML file, no chapters, appendix or image files +# chapters: all files pulled in by an XInclude statement and images. +# + +# +# This makefile is intended for Users Documentation and Functional Specifications. +# Do not use for Developer Documentation which is not installed and does not require olink. +# Refer to http://www.x.org/releases/X11R7.6/doc/xorg-docs/ReleaseNotes.html#id2584393 +# for an explanation on documents classification. +# + +# DocBook/XML generated output formats to be installed +shelf_DATA = + +# DocBook/XML file with chapters, appendix and images it includes +dist_shelf_DATA = $(docbook) $(chapters) + +if HAVE_XMLTO +if HAVE_STYLESHEETS + +XMLTO_SEARCHPATH_FLAGS = \ + --searchpath "$(XORG_SGML_PATH)/X11" \ + --searchpath "$(abs_top_builddir)" +XMLTO_HTML_OLINK_FLAGS = \ + --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.html.xml \ + --stringparam current.docid="$(<:.xml=)" +XMLTO_HTML_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl +XMLTO_HTML_FLAGS = \ + $(XMLTO_SEARCHPATH_FLAGS) \ + $(XMLTO_HTML_STYLESHEET_FLAGS) \ + $(XMLTO_HTML_OLINK_FLAGS) + +shelf_DATA += $(docbook:.xml=.html) +%.html: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) xhtml-nochunks $< + +if HAVE_XMLTO_TEXT + +shelf_DATA += $(docbook:.xml=.txt) +%.txt: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) txt $< +endif HAVE_XMLTO_TEXT + +if HAVE_FOP +XMLTO_FO_IMAGEPATH_FLAGS = --stringparam img.src.path=$(abs_builddir)/ +XMLTO_PDF_OLINK_FLAGS = \ + --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.pdf.xml \ + --stringparam current.docid="$(<:.xml=)" +XMLTO_FO_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl + +XMLTO_FO_FLAGS = \ + $(XMLTO_SEARCHPATH_FLAGS) \ + $(XMLTO_FO_STYLESHEET_FLAGS) \ + $(XMLTO_FO_IMAGEPATH_FLAGS) \ + $(XMLTO_PDF_OLINK_FLAGS) + +shelf_DATA += $(docbook:.xml=.pdf) +%.pdf: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop pdf $< + +shelf_DATA += $(docbook:.xml=.ps) +%.ps: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop ps $< +endif HAVE_FOP + +# Generate documents cross-reference target databases +if HAVE_XSLTPROC + +XSLT_SEARCHPATH_FLAGS = \ + --path "$(XORG_SGML_PATH)/X11" \ + --path "$(abs_top_builddir)" +XSLT_OLINK_FLAGS = \ + --stringparam targets.filename "$@" \ + --stringparam collect.xref.targets "only" \ + --stringparam olink.base.uri "$(@:.db=)" + +XSLT_HTML_FLAGS = \ + $(XSLT_SEARCHPATH_FLAGS) \ + $(XSLT_OLINK_FLAGS) \ + --nonet --xinclude \ + $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl +XSLT_PDF_FLAGS = \ + $(XSLT_SEARCHPATH_FLAGS) \ + $(XSLT_OLINK_FLAGS) \ + --nonet --xinclude \ + $(STYLESHEET_SRCDIR)/xorg-fo.xsl + +shelf_DATA += $(docbook:.xml=.html.db) +%.html.db: %.xml $(chapters) + $(AM_V_GEN)$(XSLTPROC) $(XSLT_HTML_FLAGS) $< + +shelf_DATA += $(docbook:.xml=.pdf.db) +%.pdf.db: %.xml $(chapters) + $(AM_V_GEN)$(XSLTPROC) $(XSLT_PDF_FLAGS) $< + +endif HAVE_XSLTPROC +endif HAVE_STYLESHEETS +endif HAVE_XMLTO + +CLEANFILES = $(shelf_DATA) diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..a62ec2a --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,74 @@ +xawincludedir=${includedir}/X11/Xaw + +xawinclude_HEADERS = \ + X11/Xaw/AllWidgets.h \ + X11/Xaw/AsciiSink.h \ + X11/Xaw/AsciiSinkP.h \ + X11/Xaw/AsciiSrc.h \ + X11/Xaw/AsciiSrcP.h \ + X11/Xaw/AsciiText.h \ + X11/Xaw/AsciiTextP.h \ + X11/Xaw/Box.h \ + X11/Xaw/BoxP.h \ + X11/Xaw/Cardinals.h \ + X11/Xaw/Command.h \ + X11/Xaw/CommandP.h \ + X11/Xaw/Dialog.h \ + X11/Xaw/DialogP.h \ + X11/Xaw/Form.h \ + X11/Xaw/FormP.h \ + X11/Xaw/Grip.h \ + X11/Xaw/GripP.h \ + X11/Xaw/Label.h \ + X11/Xaw/LabelP.h \ + X11/Xaw/List.h \ + X11/Xaw/ListP.h \ + X11/Xaw/MenuButton.h \ + X11/Xaw/MenuButtoP.h \ + X11/Xaw/MultiSrc.h \ + X11/Xaw/MultiSrcP.h \ + X11/Xaw/MultiSink.h \ + X11/Xaw/MultiSinkP.h \ + X11/Xaw/Paned.h \ + X11/Xaw/PanedP.h \ + X11/Xaw/Panner.h \ + X11/Xaw/PannerP.h \ + X11/Xaw/Porthole.h \ + X11/Xaw/PortholeP.h \ + X11/Xaw/Repeater.h \ + X11/Xaw/RepeaterP.h \ + X11/Xaw/Reports.h \ + X11/Xaw/Scrollbar.h \ + X11/Xaw/ScrollbarP.h \ + X11/Xaw/Simple.h \ + X11/Xaw/SimpleP.h \ + X11/Xaw/SimpleMenu.h \ + X11/Xaw/SimpleMenP.h \ + X11/Xaw/Sme.h \ + X11/Xaw/SmeP.h \ + X11/Xaw/SmeBSB.h \ + X11/Xaw/SmeBSBP.h \ + X11/Xaw/SmeLine.h \ + X11/Xaw/SmeLineP.h \ + X11/Xaw/StripChart.h \ + X11/Xaw/StripCharP.h \ + X11/Xaw/Template.c \ + X11/Xaw/Template.h \ + X11/Xaw/TemplateP.h \ + X11/Xaw/Text.h \ + X11/Xaw/TextP.h \ + X11/Xaw/TextSink.h \ + X11/Xaw/TextSinkP.h \ + X11/Xaw/TextSrc.h \ + X11/Xaw/TextSrcP.h \ + X11/Xaw/Tip.h \ + X11/Xaw/TipP.h \ + X11/Xaw/Toggle.h \ + X11/Xaw/ToggleP.h \ + X11/Xaw/Tree.h \ + X11/Xaw/TreeP.h \ + X11/Xaw/VendorEP.h \ + X11/Xaw/Viewport.h \ + X11/Xaw/ViewportP.h \ + X11/Xaw/XawImP.h \ + X11/Xaw/XawInit.h diff --git a/include/X11/Xaw/AllWidgets.h b/include/X11/Xaw/AllWidgets.h new file mode 100644 index 0000000..5c125d5 --- /dev/null +++ b/include/X11/Xaw/AllWidgets.h @@ -0,0 +1,37 @@ +/* + * +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +#ifndef _XawAllWidgets_h +#define _XawAllWidgets_h + +#include <X11/Xmu/WidgetNode.h> + +/* + * This file matches the generated AllWidgets.c + */ +extern XmuWidgetNode XawWidgetArray[]; +extern int XawWidgetCount; + +#endif /* _XawAllWidgets_h */ diff --git a/include/X11/Xaw/AsciiSink.h b/include/X11/Xaw/AsciiSink.h new file mode 100644 index 0000000..27d8f48 --- /dev/null +++ b/include/X11/Xaw/AsciiSink.h @@ -0,0 +1,77 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawAsciiSink_h +#define _XawAsciiSink_h + +/* + * AsciiSink Object + */ + +#include <X11/Xaw/TextSink.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + echo Output Boolean True + displayNonprinting Output Boolean True + +*/ + +#define XtCOutput "Output" + +#define XtNdisplayNonprinting "displayNonprinting" +#define XtNecho "echo" + +/* Class record constants */ +extern WidgetClass asciiSinkObjectClass; + +typedef struct _AsciiSinkClassRec *AsciiSinkObjectClass; +typedef struct _AsciiSinkRec *AsciiSinkObject; + +#endif /* _XawAsciiSink_h */ diff --git a/include/X11/Xaw/AsciiSinkP.h b/include/X11/Xaw/AsciiSinkP.h new file mode 100644 index 0000000..4bf440a --- /dev/null +++ b/include/X11/Xaw/AsciiSinkP.h @@ -0,0 +1,95 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawAsciiSinkP_h +#define _XawAsciiSinkP_h + +/* + * AsciiSink Object Private Data + */ +#include <X11/Xaw/TextSinkP.h> +#include <X11/Xaw/AsciiSink.h> + +/* New fields for the AsciiSink object class record */ +typedef struct _AsciiSinkClassPart { + XtPointer extension; +} AsciiSinkClassPart; + +/* Full class record declaration */ +typedef struct _AsciiSinkClassRec { + ObjectClassPart object_class; + TextSinkClassPart text_sink_class; + AsciiSinkClassPart ascii_sink_class; +} AsciiSinkClassRec; + +extern AsciiSinkClassRec asciiSinkClassRec; + +/* New fields for the AsciiSink object record */ +typedef struct { + /* resources */ + XFontStruct *font; /* Font to draw in. */ + Boolean echo; + Boolean display_nonprinting; + + /* private */ + GC normgc, invgc, xorgc; + XawTextPosition cursor_position; + XawTextInsertState laststate; + short cursor_x, cursor_y; /* Cursor Location. */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} AsciiSinkPart; + +/* Full instance record declaration */ +typedef struct _AsciiSinkRec { + ObjectPart object; + TextSinkPart text_sink; + AsciiSinkPart ascii_sink; +} AsciiSinkRec; + +#endif /* _XawAsciiSinkP_h */ diff --git a/include/X11/Xaw/AsciiSrc.h b/include/X11/Xaw/AsciiSrc.h new file mode 100644 index 0000000..08c5f8c --- /dev/null +++ b/include/X11/Xaw/AsciiSrc.h @@ -0,0 +1,172 @@ +/* + +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + + +/* + * AsciiSrc.h - Public Header file for Ascii Text Source. + * + * This is the public header file for the Ascii Text Source. + * It is intended to be used with the Text widget, the simplest way to use + * this text source is to use the AsciiText Object. + * + * Date: June 29, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + + +#ifndef _XawAsciiSrc_h +#define _XawAsciiSrc_h + +#include <X11/Xaw/TextSrc.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + dataCompression DataCompression Boolean True + length Length int (internal) + pieceSize PieceSize int BUFSIZ + string String String NULL + type Type XawAsciiType XawAsciiString + useStringInPlace UseStringInPlace Boolean False + +*/ + +extern WidgetClass asciiSrcObjectClass; + +typedef struct _AsciiSrcClassRec *AsciiSrcObjectClass; +typedef struct _AsciiSrcRec *AsciiSrcObject; + +#define AsciiSourceObjectClass AsciiSrcObjectClass +#define AsciiSourceObject AsciiSrcObject + +/* + * Resource Definitions + */ +#define XtCDataCompression "DataCompression" +#define XtCPieceSize "PieceSize" +#define XtCType "Type" +#define XtCUseStringInPlace "UseStringInPlace" + +#define XtNdataCompression "dataCompression" +#define XtNpieceSize "pieceSize" +#define XtNtype "type" +#define XtNuseStringInPlace "useStringInPlace" + +#define XtRAsciiType "AsciiType" + +#define XtEstring "string" +#define XtEfile "file" + +typedef enum { + XawAsciiFile, + XawAsciiString +} XawAsciiType; + +/* + * Public routines + */ + +_XFUNCPROTOBEGIN + +/* + * Function: + * XawAsciiSourceFreeString + * + * Parameters: + * w - AsciiSrc object + * + * Description: + * Frees the string returned by a get values call + * on the string when the source is of type string. + */ +void XawAsciiSourceFreeString +( + Widget w + ); + +/* + * Function: + * XawAsciiSave + * + * Arguments: + * w - asciiSrc Object. + * + * Description: + * Saves all the pieces into a file or string as required. + * + * Returns: + * True if the save was successful + */ +Bool XawAsciiSave +( + Widget w + ); + +/* + * Function: + * XawAsciiSaveAsFile + * + * Parameters: + * w - asciiSrc object + * name - name of the file to save this file into + * + * Description: + * Save the current buffer as a file. + * + * Returns: + * True if the save was successful + */ +Bool XawAsciiSaveAsFile +( + Widget w, + _Xconst char *name + ); + +/* + * Function: + * XawAsciiSourceChanged + * + * Parameters: + * w - asciiSource object + * + * Description: + * Returns true if the source has changed since last saved. + * + * Returns: + * a Boolean (see description) + */ +Bool XawAsciiSourceChanged +( + Widget w + ); + +_XFUNCPROTOEND + +#endif /* _XawAsciiSrc_h */ diff --git a/include/X11/Xaw/AsciiSrcP.h b/include/X11/Xaw/AsciiSrcP.h new file mode 100644 index 0000000..1f3f06e --- /dev/null +++ b/include/X11/Xaw/AsciiSrcP.h @@ -0,0 +1,139 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * AsciiSrcP.h - Private Header for Ascii Text Source. + * + * This is the private header file for the Ascii Text Source. + * It is intended to be used with the Text widget, the simplest way to use + * this text source is to use the AsciiText Object. + * + * Date: June 29, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _XawAsciiSrcP_h +#define _XawAsciiSrcP_h + +#include <X11/Xaw/TextSrcP.h> +#include <X11/Xaw/AsciiSrc.h> + +#ifdef L_tmpnam +#define TMPSIZ L_tmpnam +#else +#ifdef PATH_MAX +#define TMPSIZ PATH_MAX +#else +#define TMPSIZ 1024 /* bytes to allocate for tmpnam */ +#endif +#endif + +typedef struct _Piece { /* Piece of the text file of BUFSIZ allocated + characters */ + char *text; /* The text in this buffer */ + XawTextPosition used; /* The number of characters of this buffer + that have been used */ + struct _Piece *prev, *next; /* linked list pointers */ +} Piece; + +typedef struct _AsciiSrcClassPart { + XtPointer extension; +} AsciiSrcClassPart; + +/* Full class record */ +typedef struct _AsciiSrcClassRec { + ObjectClassPart object_class; + TextSrcClassPart text_src_class; + AsciiSrcClassPart ascii_src_class; +} AsciiSrcClassRec; + +extern AsciiSrcClassRec asciiSrcClassRec; + +/* New fields for the AsciiSrc object */ +typedef struct _AsciiSrcPart { + /* resources */ + char *string; /* either the string, or the + file name, depending upon the type */ + XawAsciiType type; /* either string or disk */ + XawTextPosition piece_size; /* Size of text buffer for each piece */ + Boolean data_compression; /* compress to minimum memory automatically + on save? */ +#ifdef OLDXAW + XtCallbackList callback; +#endif + Boolean use_string_in_place;/* Use the string passed in place */ + int ascii_length; /* length field for ascii string emulation */ + +#ifdef ASCII_DISK + String filename; /* name of file for Compatability */ +#endif /* ASCII_DISK */ + + /* private */ + Boolean is_tempfile; /* Is this a temporary file? */ +#ifdef OLDXAW + Boolean changes; +#endif + Boolean allocated_string; /* Have I allocated the + string in ascii_src->string? */ + XawTextPosition length; /* length of file */ + Piece *first_piece; /* first piece of the text */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} AsciiSrcPart; + +/* instance record */ +typedef struct _AsciiSrcRec { + ObjectPart object; + TextSrcPart text_src; + AsciiSrcPart ascii_src; +} AsciiSrcRec; + +#endif /* _XawAsciiSrcP_h */ diff --git a/include/X11/Xaw/AsciiText.h b/include/X11/Xaw/AsciiText.h new file mode 100644 index 0000000..b0b3cd9 --- /dev/null +++ b/include/X11/Xaw/AsciiText.h @@ -0,0 +1,123 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * AsciiText.h - Public header file for AsciiText Widget + * + * This Widget is intended to be used as a simple front end to the + * text widget with an ascii source and ascii sink attached to it + * + * Date: June 29, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ +#ifndef _AsciiText_h +#define _AsciiText_h + +#include <X11/Xaw/Text.h> +#include <X11/Xaw/AsciiSrc.h> +#include <X11/Xaw/MultiSrc.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + autoFill AutoFill Boolean False + background Background Pixel XtDefaultBackground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + bottomMargin Margin Position 2 + cursor Cursor Cursor xterm + destroyCallback Callback Pointer NULL + displayCaret Output Boolean True + displayPosition TextPosition int 0 + editType EditType XawTextEditType XawtextRead + font Font XFontStruct* Fixed + foreground Foreground Pixel Black + height Height Dimension font height + insertPosition TextPosition int 0 + international International Boolean false + leftMargin Margin Position 2 + mappedWhenManaged MappedWhenManaged Boolean True + resize Resize XawTextResizeMode XawtextResizeNever + rightMargin Margin Position 4 + scrollHorizontal Scroll XawTextScrollMode XawtextScrollNever + scrollVertical Scroll XawTextScrollMode XawtextScrollNever + selectTypes SelectTypes Pointer pos/word/line/par/all + selection Selection Pointer (empty selection) + sensitive Sensitive Boolean True + sink TextSink Widget (none) + source TextSource Widget (none) + string String String NULL + topMargin Margin Position 2 + width Width Dimension 100 + wrap Wrap XawTextWrapMode XawtextWrapNever + x Position Position 0 + y Position Position 0 + + (see also *Src.h and *Sink.h) +*/ + +typedef struct _AsciiTextClassRec *AsciiTextWidgetClass; +typedef struct _AsciiRec *AsciiWidget; + +extern WidgetClass asciiTextWidgetClass; + +/* + * Disk and String Emulation Info + */ +#ifdef ASCII_STRING +extern WidgetClass asciiStringWidgetClass; +#endif + +#ifdef ASCII_DISK +extern WidgetClass asciiDiskWidgetClass; +#endif + +#endif /* _AsciiText_h */ diff --git a/include/X11/Xaw/AsciiTextP.h b/include/X11/Xaw/AsciiTextP.h new file mode 100644 index 0000000..f91c362 --- /dev/null +++ b/include/X11/Xaw/AsciiTextP.h @@ -0,0 +1,164 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * AsciiText.c - Private header file for AsciiText Widget. + * + * This Widget is intended to be used as a simple front end to the + * text widget with an ascii source and ascii sink attached to it. + * + * Date: June 29, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _AsciiTextP_h +#define _AsciiTextP_h + +#include <X11/Xaw/TextP.h> +#include <X11/Xaw/AsciiText.h> +#include <X11/Xaw/AsciiSrc.h> +#include <X11/Xaw/MultiSrc.h> + +typedef struct { + XtPointer extension; +} AsciiClassPart; + +typedef struct _AsciiTextClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + TextClassPart text_class; + AsciiClassPart ascii_class; +} AsciiTextClassRec; + +extern AsciiTextClassRec asciiTextClassRec; + +typedef struct { + int resource; +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} AsciiPart; + +typedef struct _AsciiRec { + CorePart core; + SimplePart simple; + TextPart text; + AsciiPart ascii; +} AsciiRec; + +/* + * Ascii String Emulation widget + */ +#ifdef ASCII_STRING +typedef struct { + XtPointer extension; +} AsciiStringClassPart; + +typedef struct _AsciiStringClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + TextClassPart text_class; + AsciiClassPart ascii_class; + AsciiStringClassPart string_class; +} AsciiStringClassRec; + +extern AsciiStringClassRec asciiStringClassRec; + +typedef struct { + int resource; +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} AsciiStringPart; + +typedef struct _AsciiStringRec { + CorePart core; + SimplePart simple; + TextPart text; + AsciiPart ascii; + AsciiStringPart ascii_str; +} AsciiStringRec; +#endif /* ASCII_STRING */ + +#ifdef ASCII_DISK +/* + * Ascii Disk Emulation widget + */ +typedef struct { + XtPointer extension; +} AsciiDiskClassPart; + +typedef struct _AsciiDiskClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + TextClassPart text_class; + AsciiClassPart ascii_class; + AsciiDiskClassPart disk_class; +} AsciiDiskClassRec; + +extern AsciiDiskClassRec asciiDiskClassRec; + +typedef struct { + char resource; +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} AsciiDiskPart; + +typedef struct _AsciiDiskRec { + CorePart core; + SimplePart simple; + TextPart text; + AsciiPart ascii; + AsciiDiskPart ascii_disk; +} AsciiDiskRec; +#endif /* ASCII_DISK */ + +#endif /* _AsciiTextP_h */ diff --git a/include/X11/Xaw/Box.h b/include/X11/Xaw/Box.h new file mode 100644 index 0000000..9eb1884 --- /dev/null +++ b/include/X11/Xaw/Box.h @@ -0,0 +1,102 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawBox_h +#define _XawBox_h + +#include <X11/Xmu/Converters.h> + +/* + * Box Widget (subclass of CompositeClass) + */ + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + destroyCallback Callback Pointer NULL + displayList DisplayList XawDisplayList* NULL + hSpace HSpace Dimension 4 + height Height Dimension 0 + mappedWhenManaged MappedWhenManaged Boolean True + orientation Orientation XtOrientation vertical + vSpace VSpace Dimension 4 + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +#ifndef _XtStringDefs_h_ +#define XtNhSpace "hSpace" +#define XtNvSpace "vSpace" +#endif + +#ifndef OLDXAW +#ifndef XawNdisplayList +#define XawNdisplayList "displayList" +#endif + +#ifndef XawCDisplayList +#define XawCDisplayList "DisplayList" +#endif + +#ifndef XawRDisplayList +#define XawRDisplayList "XawDisplayList" +#endif +#endif /* OLDXAW */ + +/* Class record constants */ +extern WidgetClass boxWidgetClass; + +typedef struct _BoxClassRec *BoxWidgetClass; +typedef struct _BoxRec *BoxWidget; + +#endif /* _XawBox_h */ diff --git a/include/X11/Xaw/BoxP.h b/include/X11/Xaw/BoxP.h new file mode 100644 index 0000000..b3c2573 --- /dev/null +++ b/include/X11/Xaw/BoxP.h @@ -0,0 +1,97 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawBoxP_h +#define _XawBoxP_h + +/* + * Box Widget Private Data + */ +#include <X11/Xaw/Box.h> +#include <X11/Xmu/Converters.h> +#include <X11/Xaw/XawInit.h> + +/* New fields for the Box widget class record */ +typedef struct { + XtPointer extension; +} BoxClassPart; + +/* Full class record declaration */ +typedef struct _BoxClassRec { + CoreClassPart core_class; + CompositeClassPart composite_class; + BoxClassPart box_class; +} BoxClassRec; + +extern BoxClassRec boxClassRec; + +/* New fields for the Box widget record */ +typedef struct { + /* resources */ + Dimension h_space, v_space; + XtOrientation orientation; + + /* private state */ + Dimension preferred_width, preferred_height; + Dimension last_query_width, last_query_height; + XtGeometryMask last_query_mode; +#ifndef OLDXAW + XawDisplayList *display_list; + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} BoxPart; + +/* + * Full instance record declaration + */ +typedef struct _BoxRec { + CorePart core; + CompositePart composite; + BoxPart box; +} BoxRec; + +#endif /* _XawBoxP_h */ diff --git a/include/X11/Xaw/Cardinals.h b/include/X11/Xaw/Cardinals.h new file mode 100644 index 0000000..9a754c1 --- /dev/null +++ b/include/X11/Xaw/Cardinals.h @@ -0,0 +1,42 @@ +/* + +Copyright 1985, 1986, 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifndef _Cardinals_h +#define _Cardinals_h + +#define ZERO ((Cardinal)0) +#define ONE ((Cardinal)1) +#define TWO ((Cardinal)2) +#define THREE ((Cardinal)3) +#define FOUR ((Cardinal)4) +#define FIVE ((Cardinal)5) +#define SIX ((Cardinal)6) +#define SEVEN ((Cardinal)7) +#define EIGHT ((Cardinal)8) +#define NINE ((Cardinal)9) +#define TEN ((Cardinal)10) + +#endif /* _Cardinals_h */ diff --git a/include/X11/Xaw/Command.h b/include/X11/Xaw/Command.h new file mode 100644 index 0000000..7011fde --- /dev/null +++ b/include/X11/Xaw/Command.h @@ -0,0 +1,116 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawCommand_h +#define _XawCommand_h + +#include <X11/Xaw/Label.h> + +/* Command widget resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + accelerators Accelerators AcceleratorTable NULL + ancestorSensitive AncestorSensitive Boolean True + background Background Pixel XtDefaultBackground + backgroundPixmap Pixmap Pixmap XtUnspecifiedPixmap + bitmap Pixmap Pixmap None + borderColor BorderColor Pixel XtDefaultForeground + borderPixmap Pixmap Pixmap XtUnspecifiedPixmap + borderWidth BorderWidth Dimension 1 + callback Callback XtCallbackList NULL + colormap Colormap Colormap parent's colormap + cornerRoundPercent CornerRoundPercent Dimension 25 + cursor Cursor Cursor None + cursorName Cursor String NULL + depth Depth int parent's depth + destroyCallback Callback XtCallbackList NULL + displayList DisplayList XawDisplayList* NULL + encoding Encoding UnsignedChar XawTextEncoding8bit + font Font XFontStruct* XtDefaultFont + foreground Foreground Pixel XtDefaultForeground + height Height Dimension text height + highlightThickness Thickness Dimension 0 if shaped, else 2 + insensitiveBorder Insensitive Pixmap Gray + internalHeight Height Dimension 2 + internalWidth Width Dimension 4 + justify Justify XtJustify XtJustifyCenter + label Label String NULL + leftBitmap LeftBitmap Pixmap None + mappedWhenManaged MappedWhenManaged Boolean True + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + resize Resize Boolean True + screen Screen Screen parent's Screen + sensitive Sensitive Boolean True + shapeStyle ShapeStyle ShapeStyle Rectangle + translations Translations TranslationTable see doc or source + width Width Dimension text width + x Position Position 0 + y Position Position 0 + +*/ + +#define XtNhighlightThickness "highlightThickness" + +#define XtNshapeStyle "shapeStyle" +#define XtCShapeStyle "ShapeStyle" +#define XtRShapeStyle "ShapeStyle" +#define XtNcornerRoundPercent "cornerRoundPercent" +#define XtCCornerRoundPercent "CornerRoundPercent" + +#define XawShapeRectangle XmuShapeRectangle +#define XawShapeOval XmuShapeOval +#define XawShapeEllipse XmuShapeEllipse +#define XawShapeRoundedRectangle XmuShapeRoundedRectangle + +extern WidgetClass commandWidgetClass; + +typedef struct _CommandClassRec *CommandWidgetClass; +typedef struct _CommandRec *CommandWidget; + +#endif /* _XawCommand_h */ diff --git a/include/X11/Xaw/CommandP.h b/include/X11/Xaw/CommandP.h new file mode 100644 index 0000000..d0be64e --- /dev/null +++ b/include/X11/Xaw/CommandP.h @@ -0,0 +1,111 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawCommandP_h +#define _XawCommandP_h + +/* + * Command Widget Private Data + */ +#include <X11/Xaw/Command.h> +#include <X11/Xaw/LabelP.h> + +typedef enum { + HighlightNone, /* Do not highlight */ + HighlightWhenUnset, /* Highlight only when unset, this is + to preserve current command widget + functionality */ + HighlightAlways /* Always highlight, lets the toggle widget + and other subclasses do the right thing */ +} XtCommandHighlight; + +/* New fields for the Command widget class record */ +typedef struct _CommandClass { + XtPointer extension; +} CommandClassPart; + +/* Full class record declaration */ +typedef struct _CommandClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + LabelClassPart label_class; + CommandClassPart command_class; +} CommandClassRec; + +extern CommandClassRec commandClassRec; + +/* New fields for the Command widget record */ +typedef struct { + /* resources */ + Dimension highlight_thickness; + XtCallbackList callbacks; + + /* private state */ + Pixmap gray_pixmap; + GC normal_GC; + GC inverse_GC; + Boolean set; + XtCommandHighlight highlighted; + + /* more resources */ + int shape_style; + Dimension corner_round; + +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} CommandPart; + +/* Full widget declaration */ +typedef struct _CommandRec { + CorePart core; + SimplePart simple; + LabelPart label; + CommandPart command; +} CommandRec; + +#endif /* _XawCommandP_h */ diff --git a/include/X11/Xaw/Dialog.h b/include/X11/Xaw/Dialog.h new file mode 100644 index 0000000..442d2d2 --- /dev/null +++ b/include/X11/Xaw/Dialog.h @@ -0,0 +1,98 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawDialog_h +#define _XawDialog_h + +#include <X11/Xaw/Form.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + borderColor BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + destroyCallback Callback Pointer NULL + height Height Dimension computed at create + icon Icon Pixmap 0 + label Label String NULL + mappedWhenManaged MappedWhenManaged Boolean True + sensitive Sensitive Boolean True + value Value String NULL + width Width Dimension computed at create + x Position Position 0 + y Position Position 0 + +*/ + +#define XtCIcon "Icon" +#define XtNicon "icon" + +typedef struct _DialogClassRec *DialogWidgetClass; +typedef struct _DialogRec *DialogWidget; + +extern WidgetClass dialogWidgetClass; + +_XFUNCPROTOBEGIN + +void XawDialogAddButton +( + Widget dialog, + _Xconst char *name, + XtCallbackProc function, + XtPointer client_data + ); + +char *XawDialogGetValueString +( + Widget w +); + +_XFUNCPROTOEND + +#endif /* _XawDialog_h */ diff --git a/include/X11/Xaw/DialogP.h b/include/X11/Xaw/DialogP.h new file mode 100644 index 0000000..8fb4735 --- /dev/null +++ b/include/X11/Xaw/DialogP.h @@ -0,0 +1,100 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _DialogP_h +#define _DialogP_h + +#include <X11/Xaw/Dialog.h> +#include <X11/Xaw/FormP.h> + +typedef struct { + XtPointer extension; +} DialogClassPart; + +typedef struct _DialogClassRec { + CoreClassPart core_class; + CompositeClassPart composite_class; + ConstraintClassPart constraint_class; + FormClassPart form_class; + DialogClassPart dialog_class; +} DialogClassRec; + +extern DialogClassRec dialogClassRec; + +typedef struct _DialogPart { + /* resources */ + String label; /* description of the dialog */ + String value; /* for the user response */ + Pixmap icon; /* icon bitmap */ + + /* private */ + Widget iconW; /* widget to display the icon */ + Widget labelW; /* widget to display description */ + Widget valueW; /* user response TextWidget */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} DialogPart; + +typedef struct _DialogRec { + CorePart core; + CompositePart composite; + ConstraintPart constraint; + FormPart form; + DialogPart dialog; +} DialogRec; + +typedef struct { + XtPointer extension; +} DialogConstraintsPart; + +typedef struct _DialogConstraintsRec { + FormConstraintsPart form; + DialogConstraintsPart dialog; +} DialogConstraintsRec, *DialogConstraints; + +#endif /* _DialogP_h */ diff --git a/include/X11/Xaw/Form.h b/include/X11/Xaw/Form.h new file mode 100644 index 0000000..71a0bcc --- /dev/null +++ b/include/X11/Xaw/Form.h @@ -0,0 +1,167 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawForm_h +#define _XawForm_h + +#include <X11/Intrinsic.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + defaultDistance Thickness int 4 + destroyCallback Callback Pointer NULL + displayList DisplayList XawDisplayList* NULL + height Height Dimension computed at realize + mappedWhenManaged MappedWhenManaged Boolean True + sensitive Sensitive Boolean True + width Width Dimension computed at realize + x Position Position 0 + y Position Position 0 + +*/ + +/* Constraint parameters: + + Name Class RepType Default Value + ---- ----- ------- ------------- + bottom Edge XtEdgeType XtRubber + fromHoriz Widget Widget (left edge of form) + fromVert Widget Widget (top of form) + horizDistance Thickness int defaultDistance + left Edge XtEdgeType XtRubber + resizable Boolean Boolean False + right Edge XtEdgeType XtRubber + top Edge XtEdgeType XtRubber + vertDistance Thickness int defaultDistance + +*/ + + +#ifndef _XtStringDefs_h_ +#define XtNtop "top" +#define XtRWidget "Widget" +#endif + +#define XtNdefaultDistance "defaultDistance" +#define XtNbottom "bottom" +#define XtNleft "left" +#define XtNright "right" +#define XtNfromHoriz "fromHoriz" +#define XtNfromVert "fromVert" +#define XtNhorizDistance "horizDistance" +#define XtNvertDistance "vertDistance" +#define XtNresizable "resizable" + +#define XtCEdge "Edge" +#define XtCWidget "Widget" + +typedef enum { + XawChainTop, /* Keep this edge a constant distance from + the top of the form */ + XawChainBottom, /* Keep this edge a constant distance from + the bottom of the form */ + XawChainLeft, /* Keep this edge a constant distance from + the left of the form */ + XawChainRight, /* Keep this edge a constant distance from + the right of the form */ + XawRubber /* Keep this edge a proportional distance + from the edges of the form */ +} XawEdgeType; + +#define XtEdgeType XawEdgeType + +#define XtChainTop XawChainTop +#define XtChainBottom XawChainBottom +#define XtChainLeft XawChainLeft +#define XtChainRight XawChainRight +#define XtRubber XawRubber + +#define XtEchainLeft "chainLeft" +#define XtEchainRight "chainRight" +#define XtEchainTop "chainTop" +#define XtEchainBottom "chainBottom" +#define XtErubber "rubber" + +#ifndef OLDXAW +#ifndef XawNdisplayList +#define XawNdisplayList "displayList" +#endif + +#ifndef XawCDisplayList +#define XawCDisplayList "DisplayList" +#endif + +#ifndef XawRDisplayList +#define XawRDisplayList "XawDisplayList" +#endif +#endif + +typedef struct _FormClassRec *FormWidgetClass; +typedef struct _FormRec *FormWidget; + +extern WidgetClass formWidgetClass; + +_XFUNCPROTOBEGIN + +void XawFormDoLayout +( + Widget w, +#if NeedWidePrototypes + Bool do_layout +#else + Boolean do_layout +#endif + ); + +_XFUNCPROTOEND + +#endif /* _XawForm_h */ diff --git a/include/X11/Xaw/FormP.h b/include/X11/Xaw/FormP.h new file mode 100644 index 0000000..43a58e9 --- /dev/null +++ b/include/X11/Xaw/FormP.h @@ -0,0 +1,139 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* Form widget private definitions */ + +#ifndef _XawFormP_h +#define _XawFormP_h + +#include <X11/Xfuncproto.h> + +#include <X11/Xaw/Form.h> +#include <X11/Xaw/XawInit.h> + +_XFUNCPROTOBEGIN + +#define XtREdgeType "EdgeType" + +typedef enum { + LayoutPending, + LayoutInProgress, + LayoutDone +} LayoutState; + +#define XtInheritLayout \ +((Boolean (*)(FormWidget, unsigned int, unsigned int, Bool))_XtInherit) + +typedef struct { + Boolean(*layout)(FormWidget, unsigned int, unsigned int, Bool); +#ifndef OLDXAW + XtPointer extension; +#endif +} FormClassPart; + +typedef struct _FormClassRec { + CoreClassPart core_class; + CompositeClassPart composite_class; + ConstraintClassPart constraint_class; + FormClassPart form_class; +} FormClassRec; + +extern FormClassRec formClassRec; + +typedef struct _FormPart { + /* resources */ + int default_spacing; /* default distance between children */ + + /* private */ + Dimension old_width, old_height; /* reference value for *_virtual */ + int no_refigure; /* no re-layout while > 0 */ + Boolean needs_relayout; /* next time no_refigure == 0 */ + Boolean resize_in_layout; /* should layout() do geom request? */ + Dimension preferred_width, preferred_height; /* cached from layout */ + Boolean resize_is_no_op; /* Causes resize to take not action */ +#ifndef OLDXAW + XawDisplayList *display_list; + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} FormPart; + +typedef struct _FormRec { + CorePart core; + CompositePart composite; + ConstraintPart constraint; + FormPart form; +} FormRec; + +typedef struct _FormConstraintsPart { + /* resources */ + XtEdgeType top, bottom, left, right;/* where to drag edge on resize */ + int dx; /* desired horiz offset */ + int dy; /* desired vertical offset */ + Widget horiz_base; /* measure dx from here if non-null */ + Widget vert_base; /* measure dy from here if non-null */ + Boolean allow_resize; /* True if child may request resize */ + + /* private */ + short virtual_width, virtual_height; + Position new_x, new_y; + LayoutState layout_state; /* temporary layout state */ + Boolean deferred_resize;/* was resized while no_refigure is set */ +#ifndef OLDXAW + short virtual_x, virtual_y; + XtPointer pad[2]; /* leave some space for further optimizations + * in the form widget geometry + */ +#endif +} FormConstraintsPart; + +typedef struct _FormConstraintsRec { + FormConstraintsPart form; +} FormConstraintsRec, *FormConstraints; + +_XFUNCPROTOEND + +#endif /* _XawFormP_h */ diff --git a/include/X11/Xaw/Grip.h b/include/X11/Xaw/Grip.h new file mode 100644 index 0000000..e8892ae --- /dev/null +++ b/include/X11/Xaw/Grip.h @@ -0,0 +1,96 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Grip.h - Public Definitions for Grip widget (used by VPane Widget) + * + */ + +#ifndef _XawGrip_h +#define _XawGrip_h + +#include <X11/Xaw/Simple.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + foreground Foreground Pixel XtDefaultForeground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 0 + callback Callback Pointer GripAction + cursor Cursor Cursor None + cursorName Cursor String NULL + destroyCallback Callback Pointer NULL + height Height Dimension 8 + mappedWhenManaged MappedWhenManaged Boolean True + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + sensitive Sensitive Boolean True + width Width Dimension 8 + x Position Position 0 + y Position Position 0 + +*/ + +#define XtNgripTranslations "gripTranslations" + +typedef struct _XawGripCallData { + XEvent *event; /* the event causing the GripAction */ + String *params; /* the TranslationTable params */ + Cardinal num_params; /* count of params */ +} XawGripCallDataRec, *XawGripCallData, + GripCallDataRec, *GripCallData; /* supported for R4 compatibility */ + +/* Class Record Constant */ + +extern WidgetClass gripWidgetClass; + +typedef struct _GripClassRec *GripWidgetClass; +typedef struct _GripRec *GripWidget; + +#endif /* _XawGrip_h */ diff --git a/include/X11/Xaw/GripP.h b/include/X11/Xaw/GripP.h new file mode 100644 index 0000000..427948a --- /dev/null +++ b/include/X11/Xaw/GripP.h @@ -0,0 +1,85 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawGripP_h +#define _XawGripP_h + +#include <X11/Xaw/Grip.h> +#include <X11/Xaw/SimpleP.h> + +#define DEFAULT_GRIP_SIZE 8 + +/* New fields for the Grip widget class */ +typedef struct { + XtPointer extension; +} GripClassPart; + +/* Full Class record */ +typedef struct _GripClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + GripClassPart grip_class; +} GripClassRec; + +extern GripClassRec gripClassRec; + +/* New fields for the Grip widget */ +typedef struct { + XtCallbackList grip_action; +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} GripPart; + +/* Full instance record */ +typedef struct _GripRec { + CorePart core; + SimplePart simple; + GripPart grip; +} GripRec; + +#endif /* _XawGripP_h */ diff --git a/include/X11/Xaw/Label.h b/include/X11/Xaw/Label.h new file mode 100644 index 0000000..175f1c1 --- /dev/null +++ b/include/X11/Xaw/Label.h @@ -0,0 +1,132 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawLabel_h +#define _XawLabel_h + +/* + * Label Widget + */ + +#include <X11/Xaw/Simple.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + bitmap Pixmap Pixmap None + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + cursor Cursor Cursor None + cursorName Cursor String NULL + destroyCallback Callback XtCallbackList NULL + encoding Encoding UnsignedChar XawTextEncoding8bit + font Font XFontStruct* XtDefaultFont + foreground Foreground Pixel XtDefaultForeground + height Height Dimension text height + insensitiveBorder Insensitive Pixmap Gray + internalHeight Height Dimension 2 + internalWidth Width Dimension 4 + justify Justify XtJustify XtJustifyCenter + label Label String NULL + leftBitmap LeftBitmap Pixmap None + mappedWhenManaged MappedWhenManaged Boolean True + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + resize Resize Boolean True + sensitive Sensitive Boolean True + width Width Dimension text width + x Position Position 0 + y Position Position 0 + +*/ + +#define XawTextEncoding8bit 0 +#define XawTextEncodingChar2b 1 + +#define XtNleftBitmap "leftBitmap" +#define XtCLeftBitmap "LeftBitmap" +#define XtNencoding "encoding" +#define XtCEncoding "Encoding" + +#ifndef XtNfontSet +#define XtNfontSet "fontSet" +#endif + +#ifndef XtCFontSet +#define XtCFontSet "FontSet" +#endif + +#ifndef _XtStringDefs_h_ +#define XtNbitmap "bitmap" +#define XtNforeground "foreground" +#define XtNlabel "label" +#define XtNfont "font" +#define XtNinternalWidth "internalWidth" +#define XtNinternalHeight "internalHeight" +#define XtNresize "resize" +#define XtCResize "Resize" +#define XtCBitmap "Bitmap" +#endif + +#ifndef XtNlabelX +#define XtNlabelX "labelX" +#endif + +#ifndef XtNlabelY +#define XtNlabelY "labelY" +#endif + +/* Class record constants */ + +extern WidgetClass labelWidgetClass; + +typedef struct _LabelClassRec *LabelWidgetClass; +typedef struct _LabelRec *LabelWidget; + +#endif /* _XawLabel_h */ diff --git a/include/X11/Xaw/LabelP.h b/include/X11/Xaw/LabelP.h new file mode 100644 index 0000000..e8cc611 --- /dev/null +++ b/include/X11/Xaw/LabelP.h @@ -0,0 +1,115 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawLabelP_h +#define _XawLabelP_h + +/* + * Label Widget Private Data + */ +#include <X11/Xaw/Label.h> +#include <X11/Xaw/SimpleP.h> + +/* New fields for the Label widget class record */ +typedef struct { + XtPointer extension; +} LabelClassPart; + +/* Full class record declaration */ +typedef struct _LabelClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + LabelClassPart label_class; +} LabelClassRec; + +extern LabelClassRec labelClassRec; + +/* New fields for the Label widget record */ +typedef struct { + /* resources */ + Pixel foreground; + XFontStruct *font; + XFontSet fontset; + char *label; + XtJustify justify; + Dimension internal_width; + Dimension internal_height; + Pixmap pixmap; + Boolean resize; + unsigned char encoding; + Pixmap left_bitmap; + + /* private state */ + GC normal_GC; + GC gray_GC; + Pixmap stipple; + Position label_x; + Position label_y; + Dimension label_width; + Dimension label_height; + Dimension label_len; + int lbm_y; /* where in label */ + unsigned int lbm_width, lbm_height; /* size of pixmap */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} LabelPart; + +/* + * Full instance record declaration + */ +typedef struct _LabelRec { + CorePart core; + SimplePart simple; + LabelPart label; +} LabelRec; + +#define LEFT_OFFSET(lw) ((lw)->label.left_bitmap \ + ? (lw)->label.lbm_width + (lw)->label.internal_width \ + : 0) + +#endif /* _XawLabelP_h */ diff --git a/include/X11/Xaw/List.h b/include/X11/Xaw/List.h new file mode 100644 index 0000000..7fc59f4 --- /dev/null +++ b/include/X11/Xaw/List.h @@ -0,0 +1,234 @@ +/* +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +/* This is the List widget, it is useful to display a list, without the + * overhead of having a widget for each item in the list. It allows + * the user to select an item in a list and notifies the application through + * a callback function. + * + * Created: 8/13/88 + * By: Chris D. Peterson + * MIT X Consortium + */ + +#ifndef _XawList_h +#define _XawList_h + +#include <X11/Xaw/Simple.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + borderColor BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + callback Callback XtCallbackList NULL **6 + columnSpacing Spacing Dimension 6 + cursor Cursor Cursor left_ptr + cursorName Cursor String NULL + defaultColumns Columns int 2 **5 + destroyCallback Callback Pointer NULL + font Font XFontStruct* XtDefaultFont + forceColumns Columns Boolean False **5 + foreground Foreground Pixel XtDefaultForeground + height Height Dimension 0 **1 + insensitiveBorder Insensitive Pixmap Gray + internalHeight Height Dimension 2 + internalWidth Width Dimension 4 + list List String* NULL **2 + longest Longest int 0 **3 **4 + mappedWhenManaged MappedWhenManaged Boolean True + numberStrings NumberStrings int 0 **4 + pasteBuffer Boolean Boolean False + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + rowSpacing Spacing Dimension 4 + sensitive Sensitive Boolean True + verticalList Boolean Boolean False + width Width Dimension 0 **1 + x Position Position 0 + y Position Position 0 + + **1 - If the Width or Height of the list widget is zero (0) then the value + is set to the minimum size necessay to fit the entire list. + + If both Width and Height are zero then they are adjusted to fit the + entire list that is created width the number of default columns + specified in the defaultColumns resource. + + **2 - This is an array of strings the specify elements of the list. + This resource must be specified. + (What good is a list widget without a list?? :-) + + **3 - Longest is the length of the widest string in pixels. + + **4 - If either of these values are zero (0) then the list widget calculates + the correct value. + + (This allows you to make startup faster if you already have + this information calculated) + + NOTE: If the numberStrings value is zero the list must + be NULL terminated. + + **5 - By setting the List.Columns resource you can force the application to + have a given number of columns. + + **6 - This returns the name and index of the item selected in an + XawListReturnStruct that is pointed to by the client_data + in the CallbackProc. + +*/ + +/* + * Value returned when there are no highlighted objects + */ +#define XAW_LIST_NONE -1 + +#define XtCList "List" +#define XtCSpacing "Spacing" +#define XtCColumns "Columns" +#define XtCLongest "Longest" +#define XtCNumberStrings "NumberStrings" + +#define XtNcursor "cursor" +#define XtNcolumnSpacing "columnSpacing" +#define XtNdefaultColumns "defaultColumns" +#define XtNforceColumns "forceColumns" +#define XtNlist "list" +#define XtNlongest "longest" +#define XtNnumberStrings "numberStrings" +#define XtNpasteBuffer "pasteBuffer" +#define XtNrowSpacing "rowSpacing" +#define XtNverticalList "verticalList" +#define XtNshowCurrent "showCurrent" + +#ifndef XtNfontSet +#define XtNfontSet "fontSet" +#endif + +#ifndef XtCFontSet +#define XtCFontSet "FontSet" +#endif + +extern WidgetClass listWidgetClass; + +typedef struct _ListClassRec *ListWidgetClass; +typedef struct _ListRec *ListWidget; + +/* list return structure */ +typedef struct _XawListReturnStruct { + String string; + int list_index; +} XawListReturnStruct; + +_XFUNCPROTOBEGIN + +/* + * Function: + * XawListChange + * + * Parameters: + * w - list widget + * list - new list + * nitems - number of items in the list + * longest - length (in Pixels) of the longest element in the list + * resize - if True the the list widget will try to resize itself + * + * Description: + * Changes the list being used and shown. + * + * Note: + * If nitems of longest are <= 0 then they will be caluculated + * If nitems is <= 0 then the list needs to be NULL terminated + */ +void XawListChange +( + Widget w, + String *list, + int nitems, + int longest, +#if NeedWidePrototypes + int resize +#else + Boolean resize +#endif + ); + +/* + * Function: + * XawListUnhighlight + * + * Parameters: + * w - list widget + * + * Description: + * Unlights the current highlighted element. + */ +void XawListUnhighlight +( + Widget w + ); + +/* + * Function: + * XawListHighlight + * + * Parameters: + * w - list widget + * item - item to highlight + * + * Description: + * Highlights the given item. + */ +void XawListHighlight +( + Widget w, + int item + ); + + +/* + * Function: + * XawListShowCurrent + * + * Paraneters: + * w - list widget + * + * Description: + * Returns the currently highlighted object. + * + * Returns: + * The info about the currently highlighted object + */ + +XawListReturnStruct *XawListShowCurrent +( + Widget w + ); + +_XFUNCPROTOEND + +#endif /* _XawList_h */ diff --git a/include/X11/Xaw/ListP.h b/include/X11/Xaw/ListP.h new file mode 100644 index 0000000..5f53982 --- /dev/null +++ b/include/X11/Xaw/ListP.h @@ -0,0 +1,115 @@ +/* +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + + +/* + * This is a List widget. It allows the user to select an item in a list and + * notifies the application through a callback function. + * + * Created: 8/13/88 + * By: Chris D. Peterson + * MIT - Project Athena + */ + +#ifndef _XawListP_h +#define _XawListP_h + +/* + * List Widget Private Data + */ +#include <X11/Xaw/SimpleP.h> +#include <X11/Xaw/List.h> + +#define NO_HIGHLIGHT XAW_LIST_NONE +#define OUT_OF_RANGE -1 +#define OKAY 0 + +/* New fields for the List widget class */ +typedef struct { + XtPointer extension; +} ListClassPart; + +/* Full class record */ +typedef struct _ListClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + ListClassPart list_class; +} ListClassRec; + +extern ListClassRec listClassRec; + +/* New fields for the List widget */ +typedef struct { + /* resources */ + Pixel foreground; + Dimension internal_width; /* if not 3d, user sets directly */ + Dimension internal_height; + Dimension column_space; /* half of *_space is add on + top/bot/left of */ + Dimension row_space; /* each item's text bounding box + half added to longest for right */ + int default_cols; + Boolean force_cols; + Boolean paste; + Boolean vertical_cols; + int longest; /* in pixels */ + int nitems; + XFontStruct *font; + XFontSet fontset; /* Sheeran, Omron KK, 93/03/05 */ + String *list; /* for i18n, always in multibyte + format */ + XtCallbackList callback; + + /* private */ + int is_highlighted; /* set to the item currently + highlighted */ + int highlight; /* set to the item that should be + highlighted */ + int col_width; /* width of each column */ + int row_height; /* height of each row */ + int nrows; /* number of rows in the list */ + int ncols; /* number of columns in the list */ + GC normgc; + GC revgc; + GC graygc; + int freedoms; /* flags for resizing height + and width */ +#ifndef OLDXAW + int selected; + Boolean show_current; + char pad1[(sizeof(XtPointer) - sizeof(Boolean)) + + (sizeof(XtPointer) - sizeof(int))]; + XtPointer pad2[2]; /* for future use and keep binary compatability */ +#endif +} ListPart; + + +/* Full instance record */ +typedef struct _ListRec { + CorePart core; + SimplePart simple; + ListPart list; +} ListRec; + +#endif /* _XawListP_h */ diff --git a/include/X11/Xaw/MenuButtoP.h b/include/X11/Xaw/MenuButtoP.h new file mode 100644 index 0000000..8ee3195 --- /dev/null +++ b/include/X11/Xaw/MenuButtoP.h @@ -0,0 +1,79 @@ +/* + * +Copyright 1989,1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +/* + * MenuButtonP.h - Private Header file for MenuButton widget. + * + * This is the private header file for the Athena MenuButton widget. + * It is intended to provide an easy method of activating pulldown menus. + * + * Date: May 2, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _XawMenuButtonP_h +#define _XawMenuButtonP_h + +#include <X11/Xaw/MenuButton.h> +#include <X11/Xaw/CommandP.h> + +/* New fields for the MenuButton widget class */ +typedef struct _MenuButtonClass { + XtPointer extension; +} MenuButtonClassPart; + +/* class record declaration */ +typedef struct _MenuButtonClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + LabelClassPart label_class; + CommandClassPart command_class; + MenuButtonClassPart menuButton_class; +} MenuButtonClassRec; + +extern MenuButtonClassRec menuButtonClassRec; + +/* New fields for the MenuButton widget */ +typedef struct { + /* resources */ + String menu_name; +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} MenuButtonPart; + +/* widget declaration */ +typedef struct _MenuButtonRec { + CorePart core; + SimplePart simple; + LabelPart label; + CommandPart command; + MenuButtonPart menu_button; +} MenuButtonRec; + +#endif /* _XawMenuButtonP_h */ diff --git a/include/X11/Xaw/MenuButton.h b/include/X11/Xaw/MenuButton.h new file mode 100644 index 0000000..93f0963 --- /dev/null +++ b/include/X11/Xaw/MenuButton.h @@ -0,0 +1,89 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +/*********************************************************************** + * + * MenuButton Widget + * + ***********************************************************************/ + +/* + * MenuButton.h - Public Header file for MenuButton widget. + * + * This is the public header file for the Athena MenuButton widget. + * It is intended to provide an easy method of activating pulldown menus. + * + * Date: May 2, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _XawMenuButton_h +#define _XawMenuButton_h + +#include <X11/Xaw/Command.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + bitmap Pixmap Pixmap None + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + callback Callback Pointer NULL + cursor Cursor Cursor None + destroyCallback Callback Pointer NULL + displayList DisplayList XawDisplayList* NULL + font Font XFontStruct* XtDefaultFont + foreground Foreground Pixel XtDefaultForeground + height Height Dimension text height + highlightThickness Thickness Dimension 2 + insensitiveBorder Insensitive Pixmap Gray + internalHeight Height Dimension 2 + internalWidth Width Dimension 4 + justify Justify XtJustify XtJustifyCenter + label Label String NULL + mappedWhenManaged MappedWhenManaged Boolean True + menuName MenuName String "menu" + resize Resize Boolean True + sensitive Sensitive Boolean True + width Width Dimension text width + x Position Position 0 + y Position Position 0 + +*/ + +#define XtNmenuName "menuName" +#define XtCMenuName "MenuName" + +extern WidgetClass menuButtonWidgetClass; + +typedef struct _MenuButtonClassRec *MenuButtonWidgetClass; +typedef struct _MenuButtonRec *MenuButtonWidget; + +#endif /* _XawMenuButton_h */ diff --git a/include/X11/Xaw/MultiSink.h b/include/X11/Xaw/MultiSink.h new file mode 100644 index 0000000..3519acc --- /dev/null +++ b/include/X11/Xaw/MultiSink.h @@ -0,0 +1,110 @@ +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name OMRON is not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawMultiSink_h +#define _XawMultiSink_h + +/* + * MultiSink Object + */ + +#include <X11/Xaw/TextSink.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + echo Output Boolean True + displayNonprinting Output Boolean True + fontSet FontSet XFontSet XtDefaultFontSet + +*/ + +#define XtCOutput "Output" + +#define XtNdisplayNonprinting "displayNonprinting" +#define XtNecho "echo" + +#ifndef XtNfontSet /*Sheeran, Omron KK, 93/03/04*/ +#define XtNfontSet "fontSet" +#endif + +#ifndef XtCFontSet /*Sheeran, Omron KK, 93/03/04*/ +#define XtCFontSet "FontSet" +#endif + +/* Class record constants */ +extern WidgetClass multiSinkObjectClass; + +typedef struct _MultiSinkClassRec *MultiSinkObjectClass; +typedef struct _MultiSinkRec *MultiSinkObject; + +#endif /* _XawMultiSink_h */ diff --git a/include/X11/Xaw/MultiSinkP.h b/include/X11/Xaw/MultiSinkP.h new file mode 100644 index 0000000..019f5f4 --- /dev/null +++ b/include/X11/Xaw/MultiSinkP.h @@ -0,0 +1,138 @@ +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name OMRON not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + + +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawMultiSinkP_h +#define _XawMultiSinkP_h + +#include <X11/Xfuncproto.h> + +/* + * MultiSink Object Private Data + */ +#include <X11/Xaw/TextSinkP.h> +#include <X11/Xaw/MultiSink.h> + +/* new fields for the MultiSink object class */ +typedef struct _MultiSinkClassPart { + XtPointer extension; +} MultiSinkClassPart; + +/* Full class record declaration */ +typedef struct _MultiSinkClassRec { + ObjectClassPart object_class; + TextSinkClassPart text_sink_class; + MultiSinkClassPart multi_sink_class; +} MultiSinkClassRec; + +extern MultiSinkClassRec multiSinkClassRec; + +/* New fields for the MultiSink object record */ +typedef struct { + /* resources */ + Boolean echo; + Boolean display_nonprinting; + + /* private */ + GC normgc, invgc, xorgc; + XawTextPosition cursor_position; + XawTextInsertState laststate; + short cursor_x, cursor_y; /* Cursor Location */ + XFontSet fontset; /* font set to draw */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} MultiSinkPart; + +/* Full instance record declaration */ +typedef struct _MultiSinkRec { + ObjectPart object; + TextSinkPart text_sink; + MultiSinkPart multi_sink; +} MultiSinkRec; + +/* + * Semi-private functions + * for use by other Xaw modules only + */ +_XFUNCPROTOBEGIN + +void _XawMultiSinkPosToXY +( + Widget w, + XawTextPosition pos, + Position *x, + Position *y +); + +_XFUNCPROTOEND + +#endif /* _XawMultiSinkP_h */ diff --git a/include/X11/Xaw/MultiSrc.h b/include/X11/Xaw/MultiSrc.h new file mode 100644 index 0000000..628da0c --- /dev/null +++ b/include/X11/Xaw/MultiSrc.h @@ -0,0 +1,130 @@ +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name OMRON not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + +/* + +Copyright 1989, 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* + * This file was modified from AsciiSrc.h. + * + * By Li Yuhong, Sept. 18, 1990 + */ + +#ifndef _XawMultiSrc_h +#define _XawMultiSrc_h + +#include <X11/Xaw/TextSrc.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + dataCompression DataCompression Boolean True + length Length int (internal) + pieceSize PieceSize int BUFSIZ + string String String NULL + type Type XawAsciiType XawAsciiString + useStringInPlace UseStringInPlace Boolean False + +*/ + +extern WidgetClass multiSrcObjectClass; + +typedef struct _MultiSrcClassRec *MultiSrcObjectClass; +typedef struct _MultiSrcRec *MultiSrcObject; + +#define MultiSourceObjectClass MultiSrcObjectClass +#define MultiSourceObject MultiSrcObject + +#define XtCDataCompression "DataCompression" +#define XtCPieceSize "PieceSize" +#define XtCType "Type" +#define XtCUseStringInPlace "UseStringInPlace" + +#define XtNdataCompression "dataCompression" +#define XtNpieceSize "pieceSize" +#define XtNtype "type" +#define XtNuseStringInPlace "useStringInPlace" + +#define XtRMultiType "MultiType" + +#define XtEstring "string" +#define XtEfile "file" + +/************************************************************ + * + * THESE ROUTINES ARE NOT PUBLIC: Source should call + * + * the AsciiSrc API which currently forwards requests here. + * + * future versions (like theres going to be an R7 Xaw!) may + * + * eliminate this file or at least these functions entirely. + * + ************************************************************/ + +_XFUNCPROTOBEGIN + +void XawMultiSourceFreeString +( + Widget w + ); + +Bool _XawMultiSave +( + Widget w +); + +Bool _XawMultiSaveAsFile +( + Widget w, + _Xconst char *name + ); + +_XFUNCPROTOEND + +#endif /* _XawMultiSrc_h */ diff --git a/include/X11/Xaw/MultiSrcP.h b/include/X11/Xaw/MultiSrcP.h new file mode 100644 index 0000000..95642a4 --- /dev/null +++ b/include/X11/Xaw/MultiSrcP.h @@ -0,0 +1,179 @@ +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name OMRON not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + + +/*********************************************************** + +Copyright 1987, 1988, 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * MultiSrcP.h - Private Header for Multi Text Source. + * + * This is the private header file for the Multi Text Source. + * It is intended to be used with the Text widget, the simplest way to use + * this text source is to use the MultiText Object. + * + * Date: June 29, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +/* + * This file was changed from AsciiSrcP.h. + * + * By Li Yuhong, Sept. 18, 1990 + */ + +#ifndef _XawMultiSrcP_h +#define _XawMultiSrcP_h + +#include <X11/Xfuncproto.h> +#include <X11/Xaw/TextSrcP.h> +#include <X11/Xaw/MultiSrc.h> + +#ifdef L_tmpnam +#define TMPSIZ L_tmpnam +#else +#ifdef PATH_MAX +#define TMPSIZ PATH_MAX +#else +#define TMPSIZ 1024 /* bytes to allocate for tmpnam */ +#endif +#endif + +typedef struct _MultiPiece { /* Piece of the text file of BUFSIZ allocated + characters */ + wchar_t* text; /* The text in this buffer */ + XawTextPosition used; /* The number of characters of this buffer + that have been used */ + struct _MultiPiece *prev, *next; /* linked list pointers */ +} MultiPiece; + +/* New fields for the MultiSrc object class */ +typedef struct _MultiSrcClassPart { + XtPointer extension; +} MultiSrcClassPart; + +/* Full class record */ +typedef struct _MultiSrcClassRec { + ObjectClassPart object_class; + TextSrcClassPart text_src_class; + MultiSrcClassPart multi_src_class; +} MultiSrcClassRec; + +extern MultiSrcClassRec multiSrcClassRec; + +/* New fields for the MultiSrc object */ +typedef struct _MultiSrcPart { + /* resources */ + XIC ic; /* for X Input Method */ + XtPointer string; /* either the string, or the file name, depend- + ing upon the `type'. ALWAYS IN MB FORMAT */ + XawAsciiType type; /* either string or disk */ + XawTextPosition piece_size; /* Size of text buffer for each piece */ + Boolean data_compression; /* compress to minimum memory automatically + on save? */ +#ifdef OLDXAW + XtCallbackList callback; +#endif + Boolean use_string_in_place;/* Use the string passed in place */ + int multi_length; /* length field for multi string emulation */ + + /* private */ + + Boolean is_tempfile; /* Is this a temporary file? */ +#ifdef OLDXAW + Boolean changes; +#endif + Boolean allocated_string; /* Have I allocated the + string in multi_src->string? */ + XawTextPosition length; /* length of file - IN CHARACTERS, NOT BYTES */ + MultiPiece *first_piece; /* first piece of the text */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} MultiSrcPart; + +/* Full instance record */ +typedef struct _MultiSrcRec { + ObjectPart object; + TextSrcPart text_src; + MultiSrcPart multi_src; +} MultiSrcRec; + +_XFUNCPROTOBEGIN + +void _XawMultiSourceFreeString +( + Widget w + ); + +_XFUNCPROTOEND + +#endif /* _XawMultiSrcP_h */ diff --git a/include/X11/Xaw/Paned.h b/include/X11/Xaw/Paned.h new file mode 100644 index 0000000..4b7e115 --- /dev/null +++ b/include/X11/Xaw/Paned.h @@ -0,0 +1,258 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Paned.h - Paned Composite Widget's public header file. + * + * Updated and significantly modifided from the Athena VPaned Widget. + * + * Date: March 1, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _XawPaned_h +#define _XawPaned_h + +#include <X11/Intrinsic.h> +#include <X11/Xmu/Converters.h> + +/* RESOURCES: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + betweenCursor Cursor Cursor ** + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + cursor Cursor Cursor None + destroyCallback Callback Pointer NULL + height Height Dimension 0 + gripIndent GripIndent Position 16 + gripCursor Cursor Cursor ** + horizontalGripCursol Cursor Cursor sb_h_double_arrow + horizontalBetweencursor Cursor Cursor sb_up_arrow + internalBorderColor BorderColor Pixel XtDefaultForeground + internalBorderWidth BorderWidth Position 1 + leftCursor Cursor Cursor sb_left_arrow + lowerCursor Cursor Cursor sb_down_arrow + mappedWhenManaged MappedWhenManaged Boolean True + orientation Orientation XtOrientation XtorientVertical + refigureMode Boolean Boolean On + rightCursor Cursor Cursor sb_right_arrow + sensitive Sensitive Boolean True + upperCursor Cursor Cursor sb_up_arrow + verticalBetweenCursor Cursor Cursor sb_left_arrow + verticalGripCursor Cursor Cursor sb_v_double_arrow + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +** These resources now are set to the vertical or horizontal cursor + depending upon orientation, by default. If a value is specified here + then that cursor will be used reguardless of orientation. + + +CONSTRAINT RESOURCES: + + Name Class RepType Default Value + ---- ----- ------- ------------- + allowResize Boolean Boolean False + max Max Dimension unlimited + min Min Dimension Grip Size + preferredPaneSize PreferredPaneSize Dimension PANED_ASK_CHILD + resizeToPreferred Boolean Boolean False + showGrip ShowGrip Boolean True + skipAdjust Boolean Boolean False + +*/ + +#define PANED_ASK_CHILD 0 +#define PANED_GRIP_SIZE 0 + +#define XtNallowResize "allowResize" +#define XtNbetweenCursor "betweenCursor" +#define XtNverticalBetweenCursor "verticalBetweenCursor" +#define XtNhorizontalBetweenCursor "horizontalBetweenCursor" +#define XtNgripCursor "gripCursor" +#define XtNgripIndent "gripIndent" +#define XtNhorizontalGripCursor "horizontalGripCursor" +#define XtNinternalBorderColor "internalBorderColor" +#define XtNinternalBorderWidth "internalBorderWidth" +#define XtNleftCursor "leftCursor" +#define XtNlowerCursor "lowerCursor" +#define XtNrefigureMode "refigureMode" +#define XtNposition "position" +#define XtNmin "min" +#define XtNmax "max" +#define XtNpreferredPaneSize "preferredPaneSize" +#define XtNresizeToPreferred "resizeToPreferred" +#define XtNrightCursor "rightCursor" +#define XtNshowGrip "showGrip" +#define XtNskipAdjust "skipAdjust" +#define XtNupperCursor "upperCursor" +#define XtNverticalGripCursor "verticalGripCursor" + +#define XtCGripIndent "GripIndent" +#define XtCMin "Min" +#define XtCMax "Max" +#define XtCPreferredPaneSize "PreferredPaneSize" +#define XtCShowGrip "ShowGrip" + +/* Class record constant */ +extern WidgetClass panedWidgetClass; + +typedef struct _PanedClassRec *PanedWidgetClass; +typedef struct _PanedRec *PanedWidget; + +/* + * Public Procedures + */ + +_XFUNCPROTOBEGIN + +/* + * Function: + * XawPanedSetMinMax + * + * Parameters: + * widget - widget that is a child of the Paned widget + * min - new min and max size for the pane + * max - "" + * + * Description: + * Sets the min and max size for a pane. + */ +void XawPanedSetMinMax +( + Widget w, + int min, + int max + ); + +/* + * Function: + * XawPanedGetMinMax + * + * Parameters: + * widget - widget that is a child of the Paned widget + * min - return the current min and max size for the pane + * max - "" + * + * Description: + * Gets the min and max size for a pane. + */ +void XawPanedGetMinMax +( + Widget w, + int *min_return, + int *max_return + ); + +/* + * Function: + * XawPanedSetRefigureMode + * + * Parameters: + * w - paned widget + * mode - if False then inhibit refigure + * + * Description: + * Allows a flag to be set the will inhibit the paned widgets + * relayout routine. + */ +void XawPanedSetRefigureMode +( + Widget w, +#if NeedWidePrototypes + int mode +#else + Boolean mode +#endif + ); + +/* + * Function: + * XawPanedGetNumSub + * + * Parameters: + * w - paned widget + * + * Returns: + * Number of panes in the paned widget. + */ +int XawPanedGetNumSub +( + Widget w + ); + +/* + * Function: + * XawPanedAllowResize + * + * Parameters: + * widget - child of the paned widget + * + * Description: + * Allows a flag to be set that determines if the paned widget will + * allow geometry requests from this child + */ +void XawPanedAllowResize +( + Widget w, +#if NeedWidePrototypes + int allow_resize +#else + Boolean allow_resize +#endif + ); + +_XFUNCPROTOEND + +#endif /* _XawPaned_h */ diff --git a/include/X11/Xaw/PanedP.h b/include/X11/Xaw/PanedP.h new file mode 100644 index 0000000..4e40eaf --- /dev/null +++ b/include/X11/Xaw/PanedP.h @@ -0,0 +1,176 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Updated and significantly modified from the Athena VPaned Widget. + * + * Date: March 1, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _XawPanedP_h +#define _XawPanedP_h + +#include <X11/Xaw/Paned.h> + +/* New fields for the Paned widget class record */ +typedef struct _PanedClassPart { + XtPointer extension; +} PanedClassPart; + +/* Full Class record declaration */ +typedef struct _PanedClassRec { + CoreClassPart core_class; + CompositeClassPart composite_class; + ConstraintClassPart constraint_class; + PanedClassPart paned_class; +} PanedClassRec; + +extern PanedClassRec panedClassRec; + +/* Paned constraint record */ +typedef struct _PanedConstraintsPart { + /* Resources */ + Dimension min; /* Minimum height */ + Dimension max; /* Maximum height */ + Boolean allow_resize; /* True if child resize requests are ok */ + Boolean show_grip; /* True if child will have grip below it, + when it is not the bottom pane */ + Boolean skip_adjust; /* True if child's height should not be + changed without explicit user action */ + int position; /* position location in Paned (relative to + other children) ** NIY ** */ + Dimension preferred_size; /* The Preferred size of the pane. + If this is zero then ask child for size*/ + Boolean resize_to_pref; /* resize this pane to its preferred size + on a resize or change managed after + realize */ + + /* Private state */ + Position delta; /* Desired Location */ + Position olddelta; /* The last value of dy */ + Boolean paned_adjusted_me; /* Has the vpaned adjusted this widget w/o + user interaction to make things fit? */ + Dimension wp_size; /* widget's preferred size */ + int size; /* the size the widget will actually get */ + Widget grip; /* The grip for this child */ +} PanedConstraintsPart, *Pane; + +typedef struct _PanedConstraintsRec { + PanedConstraintsPart paned; +} PanedConstraintsRec, *PanedConstraints; + +/* + * The Pane Stack Structure + */ +typedef struct _PaneStack { + struct _PaneStack *next; /* The next element on the stack */ + Pane pane; /* The pane in this element on the stack */ + int start_size; /* The size of this element when it + was pushed onto the stack */ +} PaneStack; + +/* New Fields for the Paned widget record */ +typedef struct { + /* resources */ + Position grip_indent; /* Location of grips (offset + from right margin) */ + Boolean refiguremode; /* Whether to refigure changes + right now */ + XtTranslations grip_translations; /* grip translation table */ + Pixel internal_bp; /* color of internal borders */ + Dimension internal_bw; /* internal border width */ + XtOrientation orientation; /* Orientation of paned widget */ + + Cursor cursor; /* Cursor for paned window */ + Cursor grip_cursor; /* inactive grip cursor */ + Cursor v_grip_cursor; /* inactive vert grip cursor */ + Cursor h_grip_cursor; /* inactive horiz grip cursor */ + Cursor adjust_this_cursor; /* active grip cursor: T */ + Cursor v_adjust_this_cursor; /* active vert grip cursor: T */ + Cursor h_adjust_this_cursor; /* active horiz grip cursor: T */ + + /* vertical */ + Cursor adjust_upper_cursor; /* active grip cursor: U */ + Cursor adjust_lower_cursor; /* active grip cursor: D */ + + /* horizontal */ + Cursor adjust_left_cursor; /* active grip cursor: U */ + Cursor adjust_right_cursor; /* active grip cursor: D */ + + /* private */ + Boolean recursively_called; /* for ChangeManaged */ + Boolean resize_children_to_pref; /* override constrain resources + and resize all children to + preferred size */ + int start_loc; /* mouse origin when adjusting */ + Widget whichadd; /* Which pane to add changes to */ + Widget whichsub; /* Which pane to sub changes from */ + GC normgc; /* GC to use when drawing borders */ + GC invgc; /* GC to use when erasing borders */ + GC flipgc; /* GC to use when animating borders */ + int num_panes; /* count of managed panes */ + PaneStack *stack; /* The pane stack for this widget */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} PanedPart; + +/* + * Full instance record declaration + */ +typedef struct _PanedRec { + CorePart core; + CompositePart composite; + ConstraintPart constraint; + PanedPart paned; +} PanedRec; + +#endif /* _XawPanedP_h */ diff --git a/include/X11/Xaw/Panner.h b/include/X11/Xaw/Panner.h new file mode 100644 index 0000000..dd37602 --- /dev/null +++ b/include/X11/Xaw/Panner.h @@ -0,0 +1,105 @@ +/* + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + */ + +#ifndef _XawPanner_h +#define _XawPanner_h + +#include <X11/Intrinsic.h> +#include <X11/Xaw/Reports.h> + +/***************************************************************************** + * + * Panner Widget (subclass of Simple) + * + * This widget is used to represent navigation in a 2d coordinate system + * + * Resources: + * + * Name Class Type Default + * ---- ----- ---- ------- + * + * allowOff AllowOff Boolean FALSE + * background Background Pixel XtDefaultBackground + * backgroundStipple BackgroundStipple String NULL + * canvasWidth CanvasWidth Dimension 0 + * canvasHeight CanvasHeight Dimension 0 + * defaultScale DefaultScale Dimension 8 percent + * foreground Foreground Pixel XtDefaultBackground + * internalSpace InternalSpace Dimension 4 + * lineWidth LineWidth Dimension 0 + * reportCallback ReportCallback XtCallbackList NULL + * resize Resize Boolean TRUE + * rubberBand RubberBand Boolean FALSE + * shadowColor ShadowColor Pixel XtDefaultForeground + * shadowThickness ShadowThickness Dimension 2 + * sliderX SliderX Position 0 + * sliderY SliderY Position 0 + * sliderWidth SliderWidth Dimension 0 + * sliderHeight SliderHeight Dimension 0 + * + *****************************************************************************/ + +#ifndef _XtStringDefs_h_ +#define XtNresize "resize" +#define XtCResize "Resize" +#endif + +#define XtNallowOff "allowOff" +#define XtCAllowOff "AllowOff" +#define XtNbackgroundStipple "backgroundStipple" +#define XtCBackgroundStipple "BackgroundStipple" +#define XtNdefaultScale "defaultScale" +#define XtCDefaultScale "DefaultScale" +#define XtNcanvasWidth "canvasWidth" +#define XtCCanvasWidth "CanvasWidth" +#define XtNcanvasHeight "canvasHeight" +#define XtCCanvasHeight "CanvasHeight" +#define XtNinternalSpace "internalSpace" +#define XtCInternalSpace "InternalSpace" +#define XtNlineWidth "lineWidth" +#define XtCLineWidth "LineWidth" +#define XtNrubberBand "rubberBand" +#define XtCRubberBand "RubberBand" +#define XtNshadowThickness "shadowThickness" +#define XtCShadowThickness "ShadowThickness" +#define XtNshadowColor "shadowColor" +#define XtCShadowColor "ShadowColor" +#define XtNsliderX "sliderX" +#define XtCSliderX "SliderX" +#define XtNsliderY "sliderY" +#define XtCSliderY "SliderY" +#define XtNsliderWidth "sliderWidth" +#define XtCSliderWidth "SliderWidth" +#define XtNsliderHeight "sliderHeight" +#define XtCSliderHeight "SliderHeight" + +extern WidgetClass pannerWidgetClass; + +typedef struct _PannerClassRec *PannerWidgetClass; +typedef struct _PannerRec *PannerWidget; + +#endif /* _XawPanner_h */ diff --git a/include/X11/Xaw/PannerP.h b/include/X11/Xaw/PannerP.h new file mode 100644 index 0000000..8a7f580 --- /dev/null +++ b/include/X11/Xaw/PannerP.h @@ -0,0 +1,106 @@ +/* + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + */ + +#ifndef _XawPannerP_h +#define _XawPannerP_h + +#include <X11/Xaw/Panner.h> +#include <X11/Xaw/SimpleP.h> + +/* new fields in widget class */ +typedef struct { + XtPointer extension; +} PannerClassPart; + +/* Panner widget class */ +typedef struct _PannerClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + PannerClassPart panner_class; +} PannerClassRec; + +/* new fields in widget */ +typedef struct { + /* resources */ + XtCallbackList report_callbacks; /* callback/Callback */ + Boolean allow_off; /* allowOff/AllowOff */ + Boolean resize_to_pref; /* resizeToPreferred/Boolean */ + Pixel foreground; /* foreground/Foreground */ + Pixel shadow_color; /* shadowColor/ShadowColor */ + Dimension shadow_thickness; /* shadowThickness/ShadowThickness */ + Dimension default_scale; /* defaultScale/DefaultScale */ + Dimension line_width; /* lineWidth/LineWidth */ + Dimension canvas_width; /* canvasWidth/CanvasWidth */ + Dimension canvas_height; /* canvasHeight/CanvasHeight */ + Position slider_x; /* sliderX/SliderX */ + Position slider_y; /* sliderY/SliderY */ + Dimension slider_width; /* sliderWidth/SliderWidth */ + Dimension slider_height; /* sliderHeight/SliderHeight */ + Dimension internal_border; /* internalBorderWidth/BorderWidth */ + String stipple_name; /* backgroundStipple/BackgroundStipple + */ + /* private */ + GC slider_gc; /* background of slider */ + GC shadow_gc; /* edge of slider and shadow */ + GC xor_gc; /* for doing XOR tmp graphics */ + double haspect, vaspect; /* aspect ratio of core to canvas */ + Boolean rubber_band; /* true = rubber band, false = move */ + struct { + Boolean doing; /* tmp graphics in progress */ + Boolean showing; /* true if tmp graphics displayed */ + Position startx, starty; /* initial position of slider */ + Position dx, dy; /* offset loc for tmp graphics */ + Position x, y; /* location for tmp graphics */ + } tmp; + Position knob_x, knob_y; /* real upper left of knob in canvas */ + Dimension knob_width, knob_height; /* real size of knob in canvas */ + Boolean shadow_valid; /* true if rects are valid */ + XRectangle shadow_rects[2]; /* location of shadows */ + Position last_x, last_y; /* previous location of knob */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} PannerPart; + +typedef struct _PannerRec { + CorePart core; + SimplePart simple; + PannerPart panner; +} PannerRec; + +#define PANNER_HSCALE(pw,val) ((pw)->panner.haspect * ((double)(val))) +#define PANNER_VSCALE(pw,val) ((pw)->panner.vaspect * ((double)(val))) + +#define PANNER_DSCALE(pw,val) (Dimension) \ +((((unsigned long)(val)) * (unsigned long)pw->panner.default_scale) / 100L) + +#define PANNER_DEFAULT_SCALE 8 /* percent */ +#define PANNER_OUTOFRANGE -30000 + +extern PannerClassRec pannerClassRec; + +#endif /* _XawPannerP_h */ diff --git a/include/X11/Xaw/Porthole.h b/include/X11/Xaw/Porthole.h new file mode 100644 index 0000000..2dbcf18 --- /dev/null +++ b/include/X11/Xaw/Porthole.h @@ -0,0 +1,61 @@ +/* + * +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + */ + +#ifndef _XawPorthole_h +#define _XawPorthole_h + +#include <X11/Intrinsic.h> +#include <X11/Xaw/Reports.h> + +/***************************************************************************** + * + * Porthole Widget (subclass of Composite) + * + * This widget is similar to a viewport without scrollbars. Child movement + * is done by external panners or scrollbars. + * + * Parameters: + * + * Name Class Type Default + * ---- ----- ---- ------- + * + * background Background Pixel XtDefaultBackground + * border BorderColor Pixel XtDefaultForeground + * borderWidth BorderWidth Dimension 1 + * height Height Dimension 0 + * reportCallback ReportCallback Pointer NULL + * width Width Dimension 0 + * x Position Position 0 + * y Position Position 0 + * + *****************************************************************************/ + +extern WidgetClass portholeWidgetClass; +typedef struct _PortholeClassRec *PortholeWidgetClass; +typedef struct _PortholeRec *PortholeWidget; + +#endif /* _XawPorthole_h */ diff --git a/include/X11/Xaw/PortholeP.h b/include/X11/Xaw/PortholeP.h new file mode 100644 index 0000000..31bd65f --- /dev/null +++ b/include/X11/Xaw/PortholeP.h @@ -0,0 +1,62 @@ +/* + * +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + */ + +#ifndef _XawPortholeP_h +#define _XawPortholeP_h + +#include <X11/Xaw/Porthole.h> + +/* new fields in widget class */ +typedef struct { + XtPointer extension; +} PortholeClassPart; + +/* widget class */ +typedef struct _PortholeClassRec { + CoreClassPart core_class; + CompositeClassPart composite_class; + PortholeClassPart porthole_class; +} PortholeClassRec; + +/* new fields in widget */ +typedef struct { + /* resources */ + XtCallbackList report_callbacks; /* callback/Callback */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} PortholePart; + +typedef struct _PortholeRec { + CorePart core; + CompositePart composite; + PortholePart porthole; +} PortholeRec; + +extern PortholeClassRec portholeClassRec; + +#endif /* _XawPortholeP_h */ diff --git a/include/X11/Xaw/Repeater.h b/include/X11/Xaw/Repeater.h new file mode 100644 index 0000000..6b712ca --- /dev/null +++ b/include/X11/Xaw/Repeater.h @@ -0,0 +1,73 @@ +/* + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + */ + +#ifndef _XawRepeater_h +#define _XawRepeater_h + +#include <X11/Xaw/Command.h> + +/***************************************************************************** + * + * Repeater Widget (subclass of Command) + * + * This widget is a push button that repeatedly fires when held down + * + * Parameters: + * + * Name Class Type Default + * ---- ----- ---- ------- + * + * decay Decay int 5 milliseconds + * flash Boolean Boolean FALSE + * initialDelay Delay int 200 milliseconds + * minimumDelay MinimumDelay int 10 milliseconds + * repeatDelay Delay int 50 milliseconds + * startCallback StartCallback XtCallbackList NULL + * stopCallback StopCallback XtCallbackList NULL + * + *****************************************************************************/ + +#define XtNdecay "decay" +#define XtCDecay "Decay" +#define XtNinitialDelay "initialDelay" +#define XtCDelay "Delay" +#define XtNminimumDelay "minimumDelay" +#define XtCMinimumDelay "MinimumDelay" +#define XtNrepeatDelay "repeatDelay" +#define XtNflash "flash" +#define XtNstartCallback "startCallback" +#define XtCStartCallback "StartCallback" +#define XtNstopCallback "stopCallback" +#define XtCStopCallback "StopCallback" + + +extern WidgetClass repeaterWidgetClass; + +typedef struct _RepeaterClassRec *RepeaterWidgetClass; +typedef struct _RepeaterRec *RepeaterWidget; + +#endif /* _XawRepeater_h */ diff --git a/include/X11/Xaw/RepeaterP.h b/include/X11/Xaw/RepeaterP.h new file mode 100644 index 0000000..3eebf82 --- /dev/null +++ b/include/X11/Xaw/RepeaterP.h @@ -0,0 +1,82 @@ +/* + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + */ + +#ifndef _XawRepeaterP_h +#define _XawRepeaterP_h + +#include <X11/Xaw/CommandP.h> +#include <X11/Xaw/Repeater.h> + +/* new fields in widget class */ +typedef struct { + XtPointer extension; +} RepeaterClassPart; + +/* repeater widget class */ +typedef struct _RepeaterClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + LabelClassPart label_class; + CommandClassPart command_class; + RepeaterClassPart repeater_class; +} RepeaterClassRec; + +typedef struct { + /* resources */ + int initial_delay; /* initialDelay/Delay */ + int repeat_delay; /* repeatDelay/Delay */ + int minimum_delay; /* minimumDelay/MinimumDelay */ + int decay; /* decay to minimum delay */ + Boolean flash; /* flash/Boolean */ + XtCallbackList start_callbacks; /* startCallback/StartCallback */ + XtCallbackList stop_callbacks; /* stopCallback/StopCallback */ + + /* private */ + int next_delay; /* next amount for timer */ + XtIntervalId timer; /* timer that will fire */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} RepeaterPart; + +typedef struct _RepeaterRec { + CorePart core; + SimplePart simple; + LabelPart label; + CommandPart command; + RepeaterPart repeater; +} RepeaterRec; + + /* milliseconds */ +#define REP_DEF_DECAY 5 +#define REP_DEF_INITIAL_DELAY 200 +#define REP_DEF_MINIMUM_DELAY 10 +#define REP_DEF_REPEAT_DELAY 50 + +extern RepeaterClassRec repeaterClassRec; + +#endif /* _XawRepeaterP_h */ diff --git a/include/X11/Xaw/Reports.h b/include/X11/Xaw/Reports.h new file mode 100644 index 0000000..14a6586 --- /dev/null +++ b/include/X11/Xaw/Reports.h @@ -0,0 +1,55 @@ +/* + * +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +#ifndef _Xaw_Reports_h +#define _Xaw_Reports_h + +#include <X11/Intrinsic.h> + +/* + * XawPannerReport - this structure is used by the reportCallback of the + * Panner, Porthole, Viewport, and Scrollbar widgets to report its position. + * All fields must be filled in, although the changed field may be used as + * a hint as to which fields have been altered since the last report. + */ +typedef struct { + unsigned int changed; /* mask, see below */ + Position slider_x, slider_y; /* location of slider within outer */ + Dimension slider_width, slider_height; /* size of slider */ + Dimension canvas_width, canvas_height; /* size of canvas */ +} XawPannerReport; + +#define XawPRSliderX (1 << 0) +#define XawPRSliderY (1 << 1) +#define XawPRSliderWidth (1 << 2) +#define XawPRSliderHeight (1 << 3) +#define XawPRCanvasWidth (1 << 4) +#define XawPRCanvasHeight (1 << 5) +#define XawPRAll (63) /* union of above */ + +#define XtNreportCallback "reportCallback" +#define XtCReportCallback "reportCallback" + +#endif /* _Xaw_Reports_h */ diff --git a/include/X11/Xaw/Scrollbar.h b/include/X11/Xaw/Scrollbar.h new file mode 100644 index 0000000..904aad9 --- /dev/null +++ b/include/X11/Xaw/Scrollbar.h @@ -0,0 +1,133 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _Scrollbar_h +#define _Scrollbar_h + +/* + * Scrollbar Widget + */ + +#include <X11/Xmu/Converters.h> +#include <X11/Xfuncproto.h> + +/* Scrollbar resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + accelerators Accelerators AcceleratorTable NULL + ancestorSensitive AncestorSensitive Boolean True + background Background Pixel XtDefaultBackground + backgroundPixmap Pixmap Pixmap XtUnspecifiedPixmap + borderColor BorderColor Pixel XtDefaultForeground + borderPixmap Pixmap Pixmap XtUnspecifiedPixmap + borderWidth BorderWidth Dimension 1 + colormap Colormap Colormap parent's colormap + cursor Cursor Cursor None + cursorName Cursor String NULL + depth Depth int parent's depth + destroyCallback Callback XtCallbackList NULL + foreground Foreground Pixel XtDefaultForeground + height Height Dimension length or thickness + insensitiveBorder Insensitive Pixmap GreyPixmap + jumpProc Callback XtCallbackList NULL + length Length Dimension 1 + mappedWhenManaged MappedWhenManaged Boolean True + minimumThumb MinimumThumb Dimension 7 + orientation Orientation XtOrientation XtorientVertical + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + screen Screen Screen parent's screen + scrollDCursor Cursor Cursor XC_sb_down_arrow + scrollHCursor Cursor Cursor XC_sb_h_double_arrow + scrollLCursor Cursor Cursor XC_sb_left_arrow + scrollProc Callback XtCallbackList NULL + scrollRCursor Cursor Cursor XC_sb_right_arrow + scrollUCursor Cursor Cursor XC_sb_up_arrow + scrollVCursor Cursor Cursor XC_sb_v_double_arrow + sensitive Sensitive Boolean True + shown Shown Float 0.0 + thickness Thickness Dimension 14 + thumb Thumb Bitmap GreyPixmap + thumbProc Callback XtCallbackList NULL + topOfThumb TopOfThumb Float 0.0 + translations Translations TranslationTable see source or doc + width Width Dimension thickness or length + x Position Position 0 + y Position Position 0 + +*/ + +#define XtCMinimumThumb "MinimumThumb" +#define XtCShown "Shown" +#define XtCTopOfThumb "TopOfThumb" + +#define XtNminimumThumb "minimumThumb" +#define XtNtopOfThumb "topOfThumb" + +typedef struct _ScrollbarRec *ScrollbarWidget; +typedef struct _ScrollbarClassRec *ScrollbarWidgetClass; + +extern WidgetClass scrollbarWidgetClass; + +_XFUNCPROTOBEGIN + +void XawScrollbarSetThumb +( + Widget scrollbar, +#if NeedWidePrototypes + double top, + double shown +#else + float top, + float shown +#endif + ); + +_XFUNCPROTOEND + +#endif /* _Scrollbar_h */ diff --git a/include/X11/Xaw/ScrollbarP.h b/include/X11/Xaw/ScrollbarP.h new file mode 100644 index 0000000..b36472d --- /dev/null +++ b/include/X11/Xaw/ScrollbarP.h @@ -0,0 +1,103 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _ScrollbarP_h +#define _ScrollbarP_h + +#include <X11/Xaw/Scrollbar.h> +#include <X11/Xaw/SimpleP.h> + +typedef struct { + /* resources */ + Pixel foreground; /* thumb foreground color */ + XtOrientation orientation; /* horizontal or vertical */ + XtCallbackList scrollProc; /* proportional scroll */ + XtCallbackList thumbProc; /* jump (to position) scroll */ + XtCallbackList jumpProc; /* same as thumbProc but pass data by ref */ + Pixmap thumb; /* thumb pixmap */ + Cursor upCursor; /* scroll up cursor */ + Cursor downCursor; /* scroll down cursor */ + Cursor leftCursor; /* scroll left cursor */ + Cursor rightCursor; /* scroll right cursor */ + Cursor verCursor; /* scroll vertical cursor */ + Cursor horCursor; /* scroll horizontal cursor */ + float top; + float shown; + Dimension length; /* either height or width */ + Dimension thickness; /* either width or height */ + Dimension min_thumb; /* minium size for the thumb */ + + /* private */ + Cursor inactiveCursor; /* The normal cursor for scrollbar */ + char direction; /* a scroll has started; which direction */ + GC gc; /* a (shared) gc */ + Position topLoc; /* Pixel that corresponds to top */ + Dimension shownLength; /* Num pixels corresponding to shown */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} ScrollbarPart; + +typedef struct _ScrollbarRec { + CorePart core; + SimplePart simple; + ScrollbarPart scrollbar; +} ScrollbarRec; + +typedef struct { + XtPointer extension; +} ScrollbarClassPart; + +typedef struct _ScrollbarClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + ScrollbarClassPart scrollbar_class; +} ScrollbarClassRec; + +extern ScrollbarClassRec scrollbarClassRec; + +#endif /* _ScrollbarP_h */ diff --git a/include/X11/Xaw/Simple.h b/include/X11/Xaw/Simple.h new file mode 100644 index 0000000..ff38f16 --- /dev/null +++ b/include/X11/Xaw/Simple.h @@ -0,0 +1,113 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _Simple_h +#define _Simple_h + +#include <X11/Xmu/Converters.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + cursor Cursor Cursor None + cursorName Cursor String NULL + destroyCallback Callback Pointer NULL + displayList DisplayList XawDisplayList* NULL + height Height Dimension 0 + insensitiveBorder Insensitive Pixmap Gray + mappedWhenManaged MappedWhenManaged Boolean True + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + sensitive Sensitive Boolean True + tip Tip String NULL + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +#define XtNcursor "cursor" +#define XtNcursorName "cursorName" +#define XtNinsensitiveBorder "insensitiveBorder" + +#define XtCInsensitive "Insensitive" + +#ifndef XtCInternational +#define XtCInternational "International" +#endif + +#ifndef XtNinternational +#define XtNinternational "international" +#endif + +#ifndef OLDXAW +#ifndef XawNdisplayList +#define XawNdisplayList "displayList" +#endif + +#ifndef XawCDisplayList +#define XawCDisplayList "DisplayList" +#endif + +#ifndef XawRDisplayList +#define XawRDisplayList "XawDisplayList" +#endif + +#define XtNtip "tip" +#define XtCTip "Tip" +#endif /* OLDXAW */ + +typedef struct _SimpleClassRec *SimpleWidgetClass; +typedef struct _SimpleRec *SimpleWidget; + +extern WidgetClass simpleWidgetClass; + +#endif /* _Simple_h */ diff --git a/include/X11/Xaw/SimpleMenP.h b/include/X11/Xaw/SimpleMenP.h new file mode 100644 index 0000000..e01c151 --- /dev/null +++ b/include/X11/Xaw/SimpleMenP.h @@ -0,0 +1,99 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + */ + +/* + * SimpleMenuP.h - Private Header file for SimpleMenu widget. + * + * Date: April 3, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _SimpleMenuP_h +#define _SimpleMenuP_h + +#include <X11/Xaw/SimpleMenu.h> +#include <X11/Xaw/SmeP.h> +#include <X11/ShellP.h> +#include <X11/Xaw/XawInit.h> + +typedef struct { + XtPointer extension; /* For future needs */ +} SimpleMenuClassPart; + +typedef struct _SimpleMenuClassRec { + CoreClassPart core_class; + CompositeClassPart composite_class; + ShellClassPart shell_class; + OverrideShellClassPart override_shell_class; + SimpleMenuClassPart simpleMenu_class; +} SimpleMenuClassRec; + +extern SimpleMenuClassRec simpleMenuClassRec; + +typedef struct _SimpleMenuPart { + /* resources */ + String label_string; /* The string for the label or NULL */ + SmeObject label; /* If label_string is non-NULL then this is + the label widget */ + WidgetClass label_class; /* Widget Class of the menu label object */ + Dimension top_margin; /* Top and bottom margins */ + Dimension bottom_margin; + Dimension row_height; /* height of each row (menu entry) */ + Cursor cursor; /* The menu's cursor */ + SmeObject popup_entry; /* The entry to position the cursor on for + when using XawPositionSimpleMenu */ + Boolean menu_on_screen; /* Force the menus to be fully on the screen*/ + int backing_store; /* What type of backing store to use */ + + /* private */ + Boolean recursive_set_values; /* contain a possible infinite loop */ + Boolean menu_width; /* If true then force width to remain + core.width */ + Boolean menu_height; /* Just like menu_width, but for height */ + SmeObject entry_set; /* The entry that is currently set or + highlighted */ +#ifndef OLDXAW + Dimension left_margin; + Dimension right_margin; + XawDisplayList *display_list; + Widget sub_menu; + unsigned char state; + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} SimpleMenuPart; + +typedef struct _SimpleMenuRec { + CorePart core; + CompositePart composite; + ShellPart shell; + OverrideShellPart override; + SimpleMenuPart simple_menu; +} SimpleMenuRec; + +#endif /* _SimpleMenuP_h */ diff --git a/include/X11/Xaw/SimpleMenu.h b/include/X11/Xaw/SimpleMenu.h new file mode 100644 index 0000000..79f7216 --- /dev/null +++ b/include/X11/Xaw/SimpleMenu.h @@ -0,0 +1,171 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Chris D. Peterson, MIT X Consortium + */ + +/* + * SimpleMenu.h - Public Header file for SimpleMenu widget. + * + * This is the public header file for the Athena SimpleMenu widget. + * It is intended to provide one pane pulldown and popup menus within + * the framework of the X Toolkit. As the name implies it is a first and + * by no means complete implementation of menu code. It does not attempt to + * fill the needs of all applications, but does allow a resource oriented + * interface to menus. + * + * Date: April 3, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _SimpleMenu_h +#define _SimpleMenu_h + +#include <X11/Shell.h> +#include <X11/Xmu/Converters.h> + +/* + * SimpleMenu widget + */ + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + backgroundPixmap BackgroundPixmap Pixmap None + borderColor BorderColor Pixel XtDefaultForeground + borderPixmap BorderPixmap Pixmap None + borderWidth BorderWidth Dimension 1 + bottomMargin VerticalMargins Dimension VerticalSpace + columnWidth ColumnWidth Dimension Width of widest text + cursor Cursor Cursor None + destroyCallback Callback Pointer NULL + displayList DisplayList XawDisplayList* NULL + height Height Dimension 0 + label Label String NULL (No label) + labelClass LabelClass Pointer smeBSBObjectClass + leftMargin HorizontalMargins Dimension 0 + mappedWhenManaged MappedWhenManaged Boolean True + rightMargin HorizontalMargins Dimension 0 + rowHeight RowHeight Dimension Height of Font + sensitive Sensitive Boolean True + topMargin VerticalMargins Dimension VerticalSpace + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +typedef struct _SimpleMenuClassRec* SimpleMenuWidgetClass; +typedef struct _SimpleMenuRec* SimpleMenuWidget; + +extern WidgetClass simpleMenuWidgetClass; + +#define XtNcursor "cursor" +#define XtNbottomMargin "bottomMargin" +#define XtNcolumnWidth "columnWidth" +#define XtNlabelClass "labelClass" +#define XtNmenuOnScreen "menuOnScreen" +#define XtNpopupOnEntry "popupOnEntry" +#define XtNrowHeight "rowHeight" +#define XtNtopMargin "topMargin" +#define XtNleftMargin "leftMargin" +#define XtNrightMargin "rightMargin" + +#define XtCColumnWidth "ColumnWidth" +#define XtCLabelClass "LabelClass" +#define XtCMenuOnScreen "MenuOnScreen" +#define XtCPopupOnEntry "PopupOnEntry" +#define XtCRowHeight "RowHeight" + +#define XtCVerticalMargins "VerticalMargins" + +#ifndef OLDXAW +#define XtCHorizontalMargins "HorizontalMargins" +#define XawNdisplayList "displayList" +#define XawCDisplayList "DisplayList" +#define XawRDisplayList "XawDisplayList" +#endif + +/* + * Public Functions + */ + +_XFUNCPROTOBEGIN + +/* + * Function: + * XawSimpleMenuAddGlobalActions + * + * Parameters: + * app_con - appcontext + * + * Description: + * Adds the global actions to the simple menu widget. + */ +void XawSimpleMenuAddGlobalActions +( + XtAppContext app_con + ); + +/* + * Function: + * XawSimpleMenuGetActiveEntry + * + * Parameters: + * w - smw widget + * + * Description: + * Gets the currently active (set) entry. + * + * Returns: + * The currently set entry or NULL if none is set + */ +Widget XawSimpleMenuGetActiveEntry +( + Widget w + ); + +/* + * Function: + * XawSimpleMenuClearActiveEntry + * + * Parameters: + * w - smw widget + * + * Description: + * Unsets the currently active (set) entry. + */ +void XawSimpleMenuClearActiveEntry +( + Widget w +); + +_XFUNCPROTOEND + +#endif /* _SimpleMenu_h */ diff --git a/include/X11/Xaw/SimpleP.h b/include/X11/Xaw/SimpleP.h new file mode 100644 index 0000000..d801162 --- /dev/null +++ b/include/X11/Xaw/SimpleP.h @@ -0,0 +1,98 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _SimpleP_h +#define _SimpleP_h + +#include <X11/Xfuncproto.h> + +#include <X11/Xaw/Simple.h> + +_XFUNCPROTOBEGIN + +#include <X11/Xaw/XawInit.h> + +typedef struct { + Bool (*change_sensitive)(Widget); +#ifndef OLDXAW + XtPointer extension; +#endif +} SimpleClassPart; + +#define XtInheritChangeSensitive ((Bool (*)(Widget))_XtInherit) + +typedef struct _SimpleClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; +} SimpleClassRec; + +extern SimpleClassRec simpleClassRec; + +typedef struct { + /* resources */ + Cursor cursor; + Pixmap insensitive_border; + String cursor_name; /* cursor specified by name */ + Pixel pointer_fg, pointer_bg; /* Pointer colors */ + Boolean international; + + /* private */ +#ifndef OLDXAW + XawDisplayList *display_list; + String tip; + XtPointer pad[3]; /* for future use and keep binary compatability */ +#endif +} SimplePart; + +typedef struct _SimpleRec { + CorePart core; + SimplePart simple; +} SimpleRec; + +_XFUNCPROTOEND + +#endif /* _SimpleP_h */ diff --git a/include/X11/Xaw/Sme.h b/include/X11/Xaw/Sme.h new file mode 100644 index 0000000..b395ae7 --- /dev/null +++ b/include/X11/Xaw/Sme.h @@ -0,0 +1,71 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +/* + * This is the public header file for the Athena Sme object. + * It is intended to be used with the simple menu widget. + * + * Date: April 3, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _Sme_h +#define _Sme_h + +#include <X11/Intrinsic.h> +#include <X11/RectObj.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + callback Callback Pointer NULL + destroyCallback Callback Pointer NULL + height Height Dimension 0 + sensitive Sensitive Boolean True + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +#ifndef XtCInternational +#define XtCInternational "International" +#endif + +#ifndef XtNinternational +#define XtNinternational "international" +#endif + + +typedef struct _SmeClassRec *SmeObjectClass; +typedef struct _SmeRec *SmeObject; + +extern WidgetClass smeObjectClass; + +#endif /* _Sme_h */ diff --git a/include/X11/Xaw/SmeBSB.h b/include/X11/Xaw/SmeBSB.h new file mode 100644 index 0000000..ab6fda7 --- /dev/null +++ b/include/X11/Xaw/SmeBSB.h @@ -0,0 +1,96 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +/* + * SmeBSB.h - Public Header file for SmeBSB object. + * + * This is the public header file for the Athena BSB Sme object. + * It is intended to be used with the simple menu widget. This object + * provides bitmap - string - bitmap style entries. + * + * Date: April 3, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _SmeBSB_h +#define _SmeBSB_h + +#include <X11/Xmu/Converters.h> +#include <X11/Xaw/Sme.h> + +/* BSB Menu Entry Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + callback Callback Callback NULL + destroyCallback Callback Pointer NULL + font Font XFontStruct * XtDefaultFont + foreground Foreground Pixel XtDefaultForeground + height Height Dimension 0 + label Label String Name of entry + leftBitmap LeftBitmap Pixmap None + leftMargin HorizontalMargins Dimension 4 + menuName MenuName String NULL + rightBitmap RightBitmap Pixmap None + rightMargin HorizontalMargins Dimension 4 + sensitive Sensitive Boolean True + vertSpace VertSpace int 25 + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +typedef struct _SmeBSBClassRec *SmeBSBObjectClass; +typedef struct _SmeBSBRec *SmeBSBObject; + +extern WidgetClass smeBSBObjectClass; + +#define XtNleftBitmap "leftBitmap" +#define XtNleftMargin "leftMargin" +#define XtNrightBitmap "rightBitmap" +#define XtNrightMargin "rightMargin" +#define XtNvertSpace "vertSpace" + +#define XtNmenuName "menuName" +#define XtCMenuName "MenuName" + +#ifndef XtNfontSet +#define XtNfontSet "fontSet" +#endif + +#ifndef XtCFontSet +#define XtCFontSet "FontSet" +#endif + +#define XtCLeftBitmap "LeftBitmap" +#define XtCHorizontalMargins "HorizontalMargins" +#define XtCRightBitmap "RightBitmap" +#define XtCVertSpace "VertSpace" + +#endif /* _SmeBSB_h */ diff --git a/include/X11/Xaw/SmeBSBP.h b/include/X11/Xaw/SmeBSBP.h new file mode 100644 index 0000000..3df9b88 --- /dev/null +++ b/include/X11/Xaw/SmeBSBP.h @@ -0,0 +1,92 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Chris D. Peterson, MIT X Consortium + */ + +#ifndef _XawSmeBSBP_h +#define _XawSmeBSBP_h + +/* + * Sme Object Private Data + */ +#include <X11/Xaw/SmeP.h> +#include <X11/Xaw/SmeBSB.h> + +typedef struct _SmeBSBClassPart { + XtPointer extension; +} SmeBSBClassPart; + +/* Full class record declaration */ +typedef struct _SmeBSBClassRec { + RectObjClassPart rect_class; + SmeClassPart sme_class; + SmeBSBClassPart sme_bsb_class; +} SmeBSBClassRec; + +extern SmeBSBClassRec smeBSBClassRec; + +/* New fields for the Sme Object record */ +typedef struct { + /* resources */ + String label; /* The entry label */ + int vert_space; /* extra vert space to leave, as a + percentage of the font height of + the label */ + Pixmap left_bitmap, right_bitmap; /* bitmaps to show */ + Dimension left_margin, right_margin;/* left and right margins */ + Pixel foreground; /* foreground color */ + XFontStruct *font; /* The font to show label in */ + XFontSet fontset; /* or fontset */ + XtJustify justify; /* Justification for the label. */ + + /* private */ + Boolean set_values_area_cleared; /* do we need to unhighlight? */ + GC norm_gc; /* noral color gc */ + GC rev_gc; /* reverse color gc */ + GC norm_gray_gc; /* Normal color (grayed out) gc */ + GC invert_gc; /* gc for flipping colors */ + Dimension left_bitmap_width; /* size of each bitmap */ + Dimension left_bitmap_height; + Dimension right_bitmap_width; + Dimension right_bitmap_height; + +#ifndef OLDXAW + /* new resources */ + String menu_name; /* name of nested sub menu or NULL */ + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} SmeBSBPart; + +/* + * Full instance record declaration + */ +typedef struct _SmeBSBRec { + ObjectPart object; + RectObjPart rectangle; + SmePart sme; + SmeBSBPart sme_bsb; +} SmeBSBRec; + +#endif /* _XawSmeBSBP_h */ diff --git a/include/X11/Xaw/SmeLine.h b/include/X11/Xaw/SmeLine.h new file mode 100644 index 0000000..af4406f --- /dev/null +++ b/include/X11/Xaw/SmeLine.h @@ -0,0 +1,69 @@ +/* + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + */ + +/* + * This is the public header file for the Athena SmeLine object. + * It is intended to be used with the simple menu widget. + * + * Date: April 3, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _SmeLine_h +#define _SmeLine_h + +#include <X11/Xaw/Sme.h> +#include <X11/Xmu/Converters.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + callback Callback Pointer NULL + destroyCallback Callback Pointer NULL + height Height Dimension 0 + sensitive Sensitive Boolean True + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +#define XtCLineWidth "LineWidth" +#define XtCStipple "Stipple" + +#define XtNlineWidth "lineWidth" +#define XtNstipple "stipple" + +typedef struct _SmeLineClassRec *SmeLineObjectClass; +typedef struct _SmeLineRec *SmeLineObject; + +extern WidgetClass smeLineObjectClass; + +#endif /* _SmeLine_h */ diff --git a/include/X11/Xaw/SmeLineP.h b/include/X11/Xaw/SmeLineP.h new file mode 100644 index 0000000..ae9f1d5 --- /dev/null +++ b/include/X11/Xaw/SmeLineP.h @@ -0,0 +1,73 @@ +/* + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Chris D. Peterson, MIT X Consortium + */ + +#ifndef _XawSmeLineP_h +#define _XawSmeLineP_h + +/* + * SmeLine Widget Private Data + */ +#include <X11/Xaw/SmeP.h> +#include <X11/Xaw/SmeLine.h> + +/* New fields for the SmeLine widget class */ +typedef struct _SmeLineClassPart { + XtPointer extension; +} SmeLineClassPart; + +/* Full class record */ +typedef struct _SmeLineClassRec { + RectObjClassPart rect_class; + SmeClassPart sme_class; + SmeLineClassPart sme_line_class; +} SmeLineClassRec; + +extern SmeLineClassRec smeLineClassRec; + +/* New fields for the SmeLine widget */ +typedef struct { + /* resources */ + Pixel foreground; /* Foreground color */ + Pixmap stipple; /* Line Stipple */ + Dimension line_width; /* Width of the line */ + + /* private */ + GC gc; /* Graphics context for drawing line */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} SmeLinePart; + +/* Full instance record */ +typedef struct _SmeLineRec { + ObjectPart object; + RectObjPart rectangle; + SmePart sme; + SmeLinePart sme_line; +} SmeLineRec; + +#endif /* _XawSmeLineP_h */ diff --git a/include/X11/Xaw/SmeP.h b/include/X11/Xaw/SmeP.h new file mode 100644 index 0000000..bd4bd9d --- /dev/null +++ b/include/X11/Xaw/SmeP.h @@ -0,0 +1,88 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +/* + * This is the private header file for the Athena Sme object. + * This object is intended to be used with the simple menu widget. + * + * Date: April 3, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifndef _XawSmeP_h +#define _XawSmeP_h + +/* + * Sme Widget Private Data + */ +#include <X11/Xfuncproto.h> + +#include <X11/Xaw/Sme.h> + +_XFUNCPROTOBEGIN + +/* New fields for the Sme widget class */ +typedef struct _SmeClassPart { + XtWidgetProc highlight; + XtWidgetProc unhighlight; + XtWidgetProc notify; + XtPointer extension; +} SmeClassPart; + +/* Full class record */ +typedef struct _SmeClassRec { + RectObjClassPart rect_class; + SmeClassPart sme_class; +} SmeClassRec; + +extern SmeClassRec smeClassRec; + +/* New fields for the Sme widget */ +typedef struct { + /* resources */ + XtCallbackList callbacks; + Boolean international; +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} SmePart; + +/* Full instance record */ +typedef struct _SmeRec { + ObjectPart object; + RectObjPart rectangle; + SmePart sme; +} SmeRec; + +#define XtInheritHighlight ((XtWidgetProc)_XtInherit) +#define XtInheritUnhighlight XtInheritHighlight +#define XtInheritNotify XtInheritHighlight + +_XFUNCPROTOEND + +#endif /* _XawSmeP_h */ diff --git a/include/X11/Xaw/StripCharP.h b/include/X11/Xaw/StripCharP.h new file mode 100644 index 0000000..a0085b4 --- /dev/null +++ b/include/X11/Xaw/StripCharP.h @@ -0,0 +1,104 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawStripChartP_h +#define _XawStripChartP_h + +#include <X11/Xaw/StripChart.h> +#include <X11/Xaw/SimpleP.h> + +#define NO_GCS 0 +#define FOREGROUND (1 << 0) +#define HIGHLIGHT (1 << 1) +#define ALL_GCS (FOREGROUND | HIGHLIGHT) + +/* new fields for the stripChart widget */ +typedef struct { + /* resources */ + Pixel fgpixel; /* color index for graph */ + Pixel hipixel; /* color index for lines */ + GC fgGC; /* graphics context for fgpixel */ + GC hiGC; /* graphics context for hipixel */ + + /* private */ + int update; /* update frequence */ + int scale; /* scale factor */ + int min_scale; /* smallest scale factor */ + int interval; /* data point interval */ + XPoint *points; /* Poly point for repairing graph lines */ + double max_value; /* Max Value in window */ + double valuedata[2048]; /* record of data points */ + XtIntervalId interval_id; + XtCallbackList get_value; /* proc to call to fetch load pt */ + int jump_val; /* Amount to jump on each scroll */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} StripChartPart; + +/* instance record declaration */ +typedef struct _StripChartRec { + CorePart core; + SimplePart simple; + StripChartPart strip_chart; +} StripChartRec; + +/* new fields for the StripChart widget class record */ +typedef struct { + XtPointer extension; +} StripChartClassPart; + +/* class record declaration */ +typedef struct _StripChartClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + StripChartClassPart strip_chart_class; +} StripChartClassRec; + +extern StripChartClassRec stripChartClassRec; + +#endif /* _XawStripChartP_h */ diff --git a/include/X11/Xaw/StripChart.h b/include/X11/Xaw/StripChart.h new file mode 100644 index 0000000..17e9299 --- /dev/null +++ b/include/X11/Xaw/StripChart.h @@ -0,0 +1,116 @@ +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawStripChart_h +#define _XawStripChart_h + +#include <X11/Intrinsic.h> + +/*********************************************************************** + * + * StripChart Widget + * + ***********************************************************************/ + +/* StripChart resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + accelerators Accelerators AcceleratorTable NULL + ancestorSensitive AncestorSensitive Boolean True + background Background Pixel XtDefaultBackground + backgroundPixmap Pixmap Pixmap XtUnspecifiedPixmap + borderColor BorderColor Pixel XtDefaultForeground + borderPixmap Pixmap Pixmap XtUnspecifiedPixmap + borderWidth BorderWidth Dimension 1 + colormap Colormap Colormap parent's colormap + cursor Cursor Cursor None + cursorName Cursor String NULL + depth Depth int parent's depth + destroyCallback Callback XtCallbackList NULL + foreground Foreground Pixel XtDefaultForeground + getValue Callback XtCallbackList NULL + height Height Dimension 120 + highlight Foreground Pixel XtDefaultForeground + insensitiveBorder Insensitive Pixmap GreyPixmap + jumpScroll JumpScroll int 1/2 width + mappedWhenManaged MappedWhenManaged Boolean True + minScale Scale int 1 + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + screen Screen Screen parent's screen + sensitive Sensitive Boolean True + translations Translations TranslationTable NULL + update Interval int 10 (seconds) + width Width Dimension 120 + x Position Position 0 + y Position Position 0 + +*/ + +#define DEFAULT_JUMP -1 + +#ifndef _XtStringDefs_h_ +#define XtNhighlight "highlight" +#define XtNupdate "update" +#endif + +#define XtCJumpScroll "JumpScroll" +#define XtCScale "Scale" + +#define XtNgetValue "getValue" +#define XtNjumpScroll "jumpScroll" +#define XtNminScale "minScale" +#define XtNscale "scale" +#define XtNvmunix "vmunix" + +typedef struct _StripChartRec *StripChartWidget; +typedef struct _StripChartClassRec *StripChartWidgetClass; + +extern WidgetClass stripChartWidgetClass; + +#endif /* _XawStripChart_h */ diff --git a/include/X11/Xaw/Template.c b/include/X11/Xaw/Template.c new file mode 100644 index 0000000..6553c95 --- /dev/null +++ b/include/X11/Xaw/Template.c @@ -0,0 +1,195 @@ +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include <X11/Xaw/TemplateP.h> + +/* + * Class Methods + */ +static void TemplateInitialize(Widget, Widget, ArgList, Cardinal*); + +/* + * Prototypes + */ +static Bool TemplateFunction(TemplateWidget, int, int, Bool); + +/* + * Actions + */ +static void TemplateAction(Widget, XEvent*, String*, Cardinal*); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(TemplateRec, template.field) +static XtResource resources[] = { +/*{ + name, + class, + type, + size, + offset, + default_type, + default_addr + },*/ + { + XtNtemplateResource, + XtCTemplateResource, + XtRTemplateResource, + sizeof(char*), + offset(resource), + XtRString, + (XtPointer)"default" + }, +}; +#undef offset + +static XtActionsRec actions[] = +{ + /*{name, procedure},*/ + {"template", TemplateAction}, +}; + +static char translations[] = +"<Key>:" "template()\n" +; + +#define Superclass (&widgetClassRec) +TemplateClassRec templateClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "Template", /* class_name */ + sizeof(TemplateRec), /* widget_size */ + NULL, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + TemplateInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + actions, /* actions */ + XtNumber(actions), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + NULL, /* resize */ + NULL, /* expose */ + NULL, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + translations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* template */ + { + NULL, /* extension */ + } +}; + +WidgetClass templateWidgetClass = (WidgetClass)&templateClassRec; + +/* + * Implementation + */ +/* + * Function: + * TemplateInitialize + * + * Parameters: + * request - requested widget + * w - the widget + * args - arguments + * num_args - number of arguments + * + * Description: + * Initializes widget instance. + */ +/*ARGSUSED*/ +static void +TemplateInitialize(Widget request, Widget w, ArgList args, Cardinal *num_args) +{ + TemplateWidget tw = (TemplateWidget)w; + + tw->template.private = NULL; +} + +/* + * Function: + * TemplateFunction + * + * Parameters: + * tw - template widget + * x - x coordinate + * y - y coordinate + * force - force action + * + * Description: + * This function does nothing. + * + * Return: + * Parameter force + */ +/*ARGSUSED*/ +static Bool +TemplateFunction(TemplateWidget tw, int x, int y, Bool force) +{ + return (force); +} + +/* + * Function: + * TemplateAction + * + * Parameters: + * w - template widget + * event - event that caused this action + * params - parameters + * num_params - number of parameters + * + * Description: + * This function does nothing. + */ +/*ARGSUSED*/ +static void +TemplateAction(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ +} diff --git a/include/X11/Xaw/Template.h b/include/X11/Xaw/Template.h new file mode 100644 index 0000000..c4bb34b --- /dev/null +++ b/include/X11/Xaw/Template.h @@ -0,0 +1,67 @@ +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifndef _Template_h +#define _Template_h + +#include <X11/Intrinsic.h> + +/**************************************************************** + * + * Template widget + * + ****************************************************************/ + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + destroyCallback Callback Pointer NULL + height Height Dimension 0 + mappedWhenManaged MappedWhenManaged Boolean True + sensitive Sensitive Boolean True + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +/* define any special resource names here that are not in <X11/StringDefs.h> */ +#define XtNtemplateResource "templateResource" + +#define XtCTemplateResource "TemplateResource" + +/* declare specific TemplateWidget class and instance datatypes */ +typedef struct _TemplateClassRec *TemplateWidgetClass; +typedef struct _TemplateRec *TemplateWidget; + +/* declare the class constant */ +extern WidgetClass templateWidgetClass; + +#endif /* _Template_h */ diff --git a/include/X11/Xaw/TemplateP.h b/include/X11/Xaw/TemplateP.h new file mode 100644 index 0000000..0031d1d --- /dev/null +++ b/include/X11/Xaw/TemplateP.h @@ -0,0 +1,65 @@ +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifndef _TemplateP_h +#define _TemplateP_h + +#include <X11/Xaw/Template.h> + +/* include superclass private header file */ +#include <X11/CoreP.h> + +/* define unique representation types not found in <X11/StringDefs.h> */ +#define XtRTemplateResource "TemplateResource" + +typedef struct { + XtPointer extension; +} TemplateClassPart; + +typedef struct _TemplateClassRec { + CoreClassPart core_class; + TemplateClassPart template_class; +} TemplateClassRec; + +extern TemplateClassRec templateClassRec; + +typedef struct { + /* resources */ + char* resource; + /* private */ + char *private; +} TemplatePart; + +typedef struct _TemplateRec { + CorePart core; +#if defined(__cplusplus) || defined(c_plusplus) + TemplatePart c_template; +#else + TemplatePart template; +#endif +} TemplateRec; + +#endif /* _TemplateP_h */ diff --git a/include/X11/Xaw/Text.h b/include/X11/Xaw/Text.h new file mode 100644 index 0000000..78c1478 --- /dev/null +++ b/include/X11/Xaw/Text.h @@ -0,0 +1,370 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawText_h +#define _XawText_h + +#include <X11/Xaw/Simple.h> + +/* + + Class: textWidgetClass + Class Name: Text + Superclass: Simple + + Resources added by the Text widget: + + Name Class RepType Default Value + ---- ----- ------- ------------- + autoFill AutoFill Boolean False + bottomMargin Margin Position 2 + displayPosition TextPosition XawTextPosition 0 + insertPosition TextPosition XawTextPosition 0 + justify JustifyMode JustifyMode left + leftColumn Column Column 0 + rightColumn Column Column 0 + leftMargin Margin Position 2 + rightMargin Margin Position 4 + positionCallback Callback Callback NULL + scrollHorizontal Scroll Boolean False + scrollVertical Scroll Boolean False + selectTypes SelectTypes Pointer see documentation + textSink TextSink Widget NULL + textSource TextSource Widget NULL + topMargin Margin Position 2 + unrealizeCallback Callback Callback NULL + wrap Wrap XawTextWrapMode XawTextWrapNever + +*/ + +typedef long XawTextPosition; + +#ifndef notdef +typedef enum { + XawtextScrollNever, + XawtextScrollWhenNeeded, + XawtextScrollAlways +} XawTextScrollMode; + +typedef enum { + XawtextResizeNever, + XawtextResizeWidth, + XawtextResizeHeight, + XawtextResizeBoth +} XawTextResizeMode; +#endif + +typedef enum { + XawtextWrapNever, + XawtextWrapLine, + XawtextWrapWord +} XawTextWrapMode; + +typedef enum { + XawsdLeft, + XawsdRight +} XawTextScanDirection; + +typedef enum { + XawtextRead, + XawtextAppend, + XawtextEdit +} XawTextEditType; + +typedef enum { + XawselectNull, + XawselectPosition, + XawselectChar, + XawselectWord, + XawselectLine, + XawselectParagraph, + XawselectAll, + XawselectAlphaNumeric +} XawTextSelectType; + +typedef enum { + XawjustifyLeft, + XawjustifyRight, + XawjustifyCenter, + XawjustifyFull +} XawTextJustifyMode; + +typedef struct { + int firstPos; + int length; + char *ptr; + unsigned long format; +} XawTextBlock, *XawTextBlockPtr; + +#ifndef OLDXAW +typedef struct { + int line_number; + int column_number; + XawTextPosition insert_position; + XawTextPosition last_position; + Boolean overwrite_mode; +} XawTextPositionInfo; + +typedef struct { + XawTextPosition left, right; + XawTextBlock *block; +} XawTextPropertyInfo; + +typedef struct _XawTextAnchor XawTextAnchor; +typedef struct _XawTextEntity XawTextEntity; +typedef struct _XawTextProperty XawTextProperty; +typedef struct _XawTextPropertyList XawTextPropertyList; +#endif + +#include <X11/Xaw/TextSink.h> +#include <X11/Xaw/TextSrc.h> + +#define XtEtextScrollNever "never" +#define XtEtextScrollWhenNeeded "whenneeded" +#define XtEtextScrollAlways "always" +#define XtEtextResizeNever "never" +#define XtEtextResizeWidth "width" +#define XtEtextResizeHeight "height" +#define XtEtextResizeBoth "both" + +#define XtEtextWrapNever "never" +#define XtEtextWrapLine "line" +#define XtEtextWrapWord "word" + +#define XtNautoFill "autoFill" +#define XtNbottomMargin "bottomMargin" +#define XtNdialogHOffset "dialogHOffset" +#define XtNdialogVOffset "dialogVOffset" +#define XtNdisplayCaret "displayCaret" +#define XtNdisplayPosition "displayPosition" +#define XtNleftMargin "leftMargin" +#define XtNrightMargin "rightMargin" +#define XtNpositionCallback "positionCallback" +#define XtNscrollVertical "scrollVertical" +#define XtNscrollHorizontal "scrollHorizontal" +#define XtNselectTypes "selectTypes" +#define XtNtopMargin "topMargin" +#define XtNwrap "wrap" + +#define XtCColumn "Column" +#define XtNleftColumn "leftColumn" +#define XtNrightColumn "rightColumn" + +#define XtCJustifyMode XtCJustify +#define XtNjustifyMode XtNjustify +#define XtEtextJustifyLeft "left" +#define XtEtextJustifyRight "right" +#define XtEtextJustifyCenter "center" +#define XtEtextJustifyFull "full" + +#define XtCAutoFill "AutoFill" +#define XtCSelectTypes "SelectTypes" +#define XtCWrap "Wrap" +#ifndef notdef +#define XtCScroll "Scroll" +#endif + +#ifndef _XtStringDefs_h_ +#define XtNinsertPosition "insertPosition" +#ifndef notdef +#define XtNresize "resize" +#define XtCResize "Resize" +#endif +#define XtNselection "selection" +#endif + +/* return Error code for XawTextSearch */ +#define XawTextSearchError (-12345L) + +/* return codes from XawTextReplace */ +#define XawReplaceError -1 +#define XawEditDone 0 +#define XawEditError 1 +#define XawPositionError 2 + +/* XrmQuark is not unsigned long */ +#define XawTextFormat(tw,fmt) ((unsigned long)_XawTextFormat(tw) == (fmt)) + +extern unsigned long FMT8BIT; +extern unsigned long XawFmt8Bit; +extern unsigned long XawFmtWide; + +extern WidgetClass textWidgetClass; + +typedef struct _TextClassRec *TextWidgetClass; +typedef struct _TextRec *TextWidget; + +_XFUNCPROTOBEGIN + +XrmQuark _XawTextFormat +( + TextWidget tw + ); + +void XawTextDisplay +( + Widget w + ); + +void XawTextEnableRedisplay +( + Widget w + ); + +void XawTextDisableRedisplay +( + Widget w + ); + +void XawTextSetSelectionArray +( + Widget w, + XawTextSelectType *sarray + ); + +void XawTextGetSelectionPos +( + Widget w, + XawTextPosition *begin_return, + XawTextPosition *end_return + ); + +void XawTextSetSource +( + Widget w, + Widget source, + XawTextPosition top + ); + +int XawTextReplace +( + Widget w, + XawTextPosition start, + XawTextPosition end, + XawTextBlock *text + ); + +XawTextPosition XawTextTopPosition +( + Widget w + ); + +XawTextPosition XawTextLastPosition +( + Widget w + ); + +void XawTextSetInsertionPoint +( + Widget w, + XawTextPosition position + ); + +XawTextPosition XawTextGetInsertionPoint +( + Widget w + ); + +void XawTextUnsetSelection +( + Widget w + ); + +void XawTextSetSelection +( + Widget w, + XawTextPosition left, + XawTextPosition right + ); + +void XawTextInvalidate +( + Widget w, + XawTextPosition from, + XawTextPosition to +); + +Widget XawTextGetSource +( + Widget w + ); + +Widget XawTextGetSink +( + Widget w + ); + +XawTextPosition XawTextSearch +( + Widget w, +#if NeedWidePrototypes + int dir, +#else + XawTextScanDirection dir, +#endif + XawTextBlock *text + ); + +void XawTextDisplayCaret +( + Widget w, +#if NeedWidePrototypes + int visible +#else + Boolean visible +#endif + ); + +_XFUNCPROTOEND + +/* + * For R3 compatability only + */ +#include <X11/Xaw/AsciiSrc.h> +#include <X11/Xaw/AsciiSink.h> + +#endif /* _XawText_h */ diff --git a/include/X11/Xaw/TextP.h b/include/X11/Xaw/TextP.h new file mode 100644 index 0000000..60f4624 --- /dev/null +++ b/include/X11/Xaw/TextP.h @@ -0,0 +1,317 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawTextP_h +#define _XawTextP_h + +#include <X11/Xfuncproto.h> + +#include <X11/Xaw/Text.h> +#include <X11/Xaw/SimpleP.h> + +_XFUNCPROTOBEGIN + +#define MAXCUT 30000 /* Maximum number of characters that can be cut */ + +#define XawTextGetLastPosition(ctx) \ + XawTextSourceScan((ctx)->text.source, 0, \ + XawstAll, XawsdRight, 1, True) +#define GETLASTPOS XawTextGetLastPosition(ctx) + +#define zeroPosition ((XawTextPosition)0) + +extern XtActionsRec _XawTextActionsTable[]; +extern Cardinal _XawTextActionsTableCount; + +extern char _XawDefaultTextTranslations[]; + +#define XawLF 0x0a +#define XawCR 0x0d +#define XawTAB 0x09 +#define XawBS 0x08 +#define XawSP 0x20 +#define XawDEL 0x7f +#define XawESC 0x1b +#define XawBSLASH '\\' + +/* constants that subclasses may want to know */ +#define DEFAULT_TEXT_HEIGHT ((Dimension)~0) +#define DEFAULT_TAB_SIZE 8 + +/* displayable text management data structures */ +typedef struct { + XawTextPosition position; + Position y; +#ifndef OLDXAW + unsigned int textWidth; +#else + Dimension textWidth; +#endif +} XawTextLineTableEntry, *XawTextLineTableEntryPtr; + +typedef struct { + XawTextPosition left, right; + XawTextSelectType type; + Atom *selections; + int atom_count; + int array_size; +} XawTextSelection; + +typedef struct _XawTextSelectionSalt { + struct _XawTextSelectionSalt *next; + XawTextSelection s; + /* + * The element "contents" stores the CT string which is gotten in the + * function _XawTextSaltAwaySelection() + */ + char *contents; + int length; +} XawTextSelectionSalt; + +#ifndef OLDXAW +typedef struct _XawTextKillRing { + struct _XawTextKillRing *next; + char *contents; + int length; + unsigned refcount; + unsigned long format; +} XawTextKillRing; + +extern XawTextKillRing *xaw_text_kill_ring; +#endif + +/* Line Tables are n+1 long - last position displayed is in last lt entry */ +typedef struct { + XawTextPosition top; /* Top of the displayed text */ + int lines; /* How many lines in this table */ +#ifndef OLDXAW + int base_line; /* line number of first entry */ +#endif + XawTextLineTableEntry *info; /* A dynamic array, one entry per line */ +} XawTextLineTable, *XawTextLineTablePtr; + +typedef struct _XawTextMargin { + Position left, right, top, bottom; +} XawTextMargin; + +typedef struct _XmuScanline XmuTextUpdate; + +#define VMargins(ctx) ((ctx)->text.margin.top + (ctx)->text.margin.bottom) +#define HMargins(ctx) ((ctx)->text.left_margin + (ctx)->text.margin.right) +#define RVMargins(ctx) ((ctx)->text.r_margin.top + (ctx)->text.r_margin.bottom) +#define RHMargins(ctx) ((ctx)->text.r_margin.left + (ctx)->text.r_margin.right) + +#define IsPositionVisible(ctx, pos) \ +(pos >= ctx->text.lt.info[0].position && \ + pos < ctx->text.lt.info[ctx->text.lt.lines].position) + +/* + * Search & Replace data structure + */ +struct SearchAndReplace { + Boolean selection_changed; /* flag so that the selection cannot be + changed out from underneath query-replace.*/ + Widget search_popup; /* The poppup widget that allows searches.*/ + Widget label1; /* The label widgets for the search window. */ + Widget label2; + Widget left_toggle; /* The left search toggle radioGroup. */ + Widget right_toggle; /* The right search toggle radioGroup. */ + Widget rep_label; /* The Replace label string. */ + Widget rep_text; /* The Replace text field. */ + Widget search_text; /* The Search text field. */ + Widget rep_one; /* The Replace one button. */ + Widget rep_all; /* The Replace all button. */ +#ifndef OLDXAW + Widget case_sensitive; /* The "Case Sensitive" toggle */ +#endif +}; + +/* New fields for the Text widget class record */ +typedef struct { + XtPointer extension; +} TextClassPart; + +/* Full class record declaration */ +typedef struct _TextClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + TextClassPart text_class; +} TextClassRec; + +extern TextClassRec textClassRec; + +/* New fields for the Text widget record */ +typedef struct _TextPart { + /* resources */ + Widget source, sink; + XawTextPosition insertPos; + XawTextSelection s; + XawTextSelectType *sarray; /* Array to cycle for selections */ + XawTextSelectionSalt *salt; /* salted away selections */ + int left_margin; + int dialog_horiz_offset, dialog_vert_offset; /* position for popup dialog */ + Boolean display_caret; /* insertion pt visible iff T */ + Boolean auto_fill; /* Auto fill mode? */ + XawTextScrollMode scroll_vert, scroll_horiz; + XawTextWrapMode wrap; /* The type of wrapping */ + XawTextResizeMode resize; + XawTextMargin r_margin; /* The real margins */ +#ifndef OLDXAW + XtCallbackList position_callbacks; +#else + XtPointer pad1; +#endif + + /* private state */ + XawTextMargin margin; /* The current margins */ + XawTextLineTable lt; + XawTextScanDirection extendDir; + XawTextSelection origSel; /* the selection being modified */ + Time lasttime; /* timestamp of last processed action */ + Time time; /* time of last key or button action */ + Position ev_x, ev_y; /* x, y coords for key or button action */ + Widget vbar, hbar; /* The scroll bars (none = NULL) */ + struct SearchAndReplace *search; /* Search and replace structure */ + Widget file_insert; /* The file insert popup widget */ + XmuTextUpdate *update; /* Position intervals to update */ +#ifndef OLDXAW + int line_number; + short column_number; + unsigned char kill_ring; + Boolean selection_state; +#else + XtPointer pad2; + int pad3; +#endif + int from_left; /* Cursor position */ + XawTextPosition lastPos; /* Last position of source */ + GC gc; + Boolean showposition; /* True if we need to show the position */ + Boolean hasfocus; /* TRUE if we currently have input focus*/ + Boolean update_disabled; /* TRUE if display updating turned off */ + Boolean clear_to_eol; /* Clear to eol when painting text? */ + XawTextPosition old_insert; /* Last insertPos for batched updates */ + short mult; /* Multiplier */ +#ifndef OLDXAW + XawTextKillRing *kill_ring_ptr; +#else + XtPointer pad4; +#endif + + /* private state, shared w/Source and Sink */ + Boolean redisplay_needed; /* in SetValues */ + XawTextSelectionSalt *salt2; /* salted away selections */ + +#ifndef OLDXAW + char numeric; + char source_changed; + Boolean overwrite; /* Overwrite mode */ + + /* new resources and states, for text edition + * Note: a fixed width font is required for these resources/states. + */ + short left_column, right_column; + XawTextJustifyMode justify; + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} TextPart; + +#define XtRWrapMode "WrapMode" +#define XtRScrollMode "ScrollMode" +#define XtRResizeMode "ResizeMode" +#define XtRJustifyMode "JustifyMode" + +/* full instance record */ +typedef struct _TextRec { + CorePart core; + SimplePart simple; + TextPart text; +} TextRec; + +/* + * Semi-private functions + * for use by other Xaw modules only + */ +void _XawTextBuildLineTable +( + TextWidget ctx, + XawTextPosition top_pos, + _XtBoolean force_rebuild + ); + +char *_XawTextGetSTRING +( + TextWidget ctx, + XawTextPosition left, + XawTextPosition right + ); + +void _XawTextSaltAwaySelection +( + TextWidget ctx, + Atom *selections, + int num_atoms + ); + +void _XawTextPosToXY +( + Widget w, + XawTextPosition pos, + Position *x, + Position *y + ); + +void _XawTextNeedsUpdating +( + TextWidget ctx, + XawTextPosition left, + XawTextPosition right + ); + +_XFUNCPROTOEND + +#endif /* _XawTextP_h */ diff --git a/include/X11/Xaw/TextSink.h b/include/X11/Xaw/TextSink.h new file mode 100644 index 0000000..f3dd968 --- /dev/null +++ b/include/X11/Xaw/TextSink.h @@ -0,0 +1,359 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawTextSink_h +#define _XawTextSink_h + +#include <X11/Xaw/Text.h> + +/*********************************************************************** + * + * TextSink Object + * + ***********************************************************************/ + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + font Font XFontStruct * XtDefaultFont + foreground Foreground Pixel XtDefaultForeground + background Background Pixel XtDefaultBackground + cursorColor Color Pixel XtDefaultForeground +*/ + +/* Class record constants */ + +extern WidgetClass textSinkObjectClass; + +typedef struct _TextSinkClassRec *TextSinkObjectClass; +typedef struct _TextSinkRec *TextSinkObject; + +typedef enum {XawisOn, XawisOff} XawTextInsertState; + +#ifndef OLDXAW +#ifndef XtNcursorColor +#define XtNcursorColor "cursorColor" +#endif + +#define XawNtextProperties "textProperties" +#define XawCTextProperties "TextProperties" +#define XawRTextProperties "XawTextProperties" +#endif + +/* + * Public Functions + */ +_XFUNCPROTOBEGIN + +/* + * Function: + * XawTextSinkDisplayText + * + * Parameters: + * w - the TextSink Object + * x - location to start drawing text + * y - "" + * pos1 - location of starting and ending points in the text buffer + * pos2 - "" + * highlight - hightlight this text? + * + * Description: + * Stub function that in subclasses will display text. + * + * Note: + * This function doesn't actually display anything, it is only a place + * holder. + */ +void XawTextSinkDisplayText +( + Widget w, +#if NeedWidePrototypes + int x, + int y, +#else + Position x, + Position y, +#endif + XawTextPosition pos1, + XawTextPosition pos2, +#if NeedWidePrototypes + int highlight +#else + Boolean highlight +#endif + ); + +/* + * Function: + * XawTextSinkInsertCursor + * + * Parameters: + * w - the TextSink Object. + * x - location for the cursor. + * y - "" + * state - whether to turn the cursor on, or off + * + * Description: + * Places the InsertCursor. + * + * Note: + * This function doesn't actually display anything, it is only a place + * holder. + */ +void XawTextSinkInsertCursor +( + Widget w, +#if NeedWidePrototypes + int x, + int y, + int state +#else + Position x, + Position y, + XawTextInsertState state +#endif + ); + +/* + * Function: + * XawTextSinkClearToBackground + * + * Parameters: + * w - TextSink Object + * x - location of area to clear + * y - "" + * width - size of area to clear + * height - "" + * + * Description: + * Clears a region of the sink to the background color. + * + * Note: + * This function doesn't actually display anything, it is only a place + * holder. + */ +void XawTextSinkClearToBackground +( + Widget w, +#if NeedWidePrototypes + int x, + int y, + unsigned int width, + unsigned int height +#else + Position x, + Position y, + Dimension width, + Dimension height +#endif + ); + +/* + * Function: + * XawTextSinkFindPosition + * + * Parameters: + * w - TextSink Object + * fromPos - reference position + * fromX - reference location + * width - width of section to paint text + * stopAtWordBreak - returned position is a word break? + * resPos - Position to return + * resWidth - Width actually used + * resHeight - Height actually used + * + * Description: + * Finds a position in the text. + */ +void XawTextSinkFindPosition +( + Widget w, + XawTextPosition fromPos, + int fromX, + int width, +#if NeedWidePrototypes + int stopAtWordBreak, +#else + Boolean stopAtWordBreak, +#endif + XawTextPosition* pos_return, + int *width_return, + int *height_return + ); + +/* + * Function: + * XawTextSinkFindDistance + * + * Parameters: + * w - TextSink Object + * fromPos - starting Position + * fromX - x location of starting Position + * toPos - end Position + * resWidth - Distance between fromPos and toPos + * resPos - Acutal toPos used + * resHeight - Height required by this text + * + * Description: + * Find the Pixel Distance between two text Positions. + */ +void XawTextSinkFindDistance +( + Widget w, + XawTextPosition fromPos, + int fromX, + XawTextPosition toPos, + int *width_return, + XawTextPosition *pos_return, + int *height_return + ); + +/* + * Function: + * XawTextSinkResolve + * + * Parameters: + * w - TextSink Object + * pos - reference Position + * fromx - reference Location + * width - width to move + * resPos - resulting position + * + * Description: + * Resloves a location to a position. + */ +void XawTextSinkResolve +( + Widget w, + XawTextPosition fromPos, + int fromX, + int width, + XawTextPosition *pos_return + ); + +/* + * Function: + * XawTextSinkMaxLines + * + * Parameters: + * w - TextSink Object + * height - height to fit lines into + * + * Returns: + * Number of lines that will fit + * + * Description: + * Finds the Maximum number of lines that will fit in a given height. + */ +int XawTextSinkMaxLines +( + Widget w, +#if NeedWidePrototypes + unsigned int height +#else + Dimension height +#endif + ); + +/* + * Function: + * XawTextSinkMaxHeight + * + * Parameters: + * w - TextSink Object + * lines - number of lines + * + * Returns: + * Height + * + * Description: + * Finds the Minium height that will contain a given number lines. + */ +int XawTextSinkMaxHeight +( + Widget w, + int lines +); + +/* + * Function: + * XawTextSinkSetTabs + * + * Parameters: + * w - TextSink Object + * tab_count - number of tabs in the list + * tabs - text positions of the tabs + * Description: + * Sets the Tab stops. + */ +void XawTextSinkSetTabs +( + Widget w, + int tab_count, + int *tabs +); + +/* + * Function: + * XawTextSinkGetCursorBounds + * + * Parameters: + * w - TextSink Object + * rect - X rectance containing the cursor bounds + * Description: + * Finds the bounding box for the insert curor (caret). + */ +void XawTextSinkGetCursorBounds +( + Widget w, + XRectangle *rect_return +); + +_XFUNCPROTOEND + +#endif /* _XawTextSink_h */ diff --git a/include/X11/Xaw/TextSinkP.h b/include/X11/Xaw/TextSinkP.h new file mode 100644 index 0000000..78f41d2 --- /dev/null +++ b/include/X11/Xaw/TextSinkP.h @@ -0,0 +1,300 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawTextSinkP_h +#define _XawTextSinkP_h + +/* + * TextSink Object Private Data + */ +#include <X11/Xaw/TextSink.h> +#include <X11/Xaw/TextP.h> /* This sink works with the Text widget */ +#include <X11/Xaw/TextSrcP.h> /* This sink works with the Text Source */ +#include <X11/Xmu/Xmu.h> + +#ifndef OLDXAW +/* font/fontset defined? */ +#define XAW_TPROP_FONT (1<<0) +#define XAW_TPROP_FONTSET (1<<1) + +/* extra attributes */ +#define XAW_TPROP_FOREGROUND (1<<2) +#define XAW_TPROP_BACKGROUND (1<<3) +#define XAW_TPROP_FPIXMAP (1<<4) +#define XAW_TPROP_BPIXMAP (1<<5) +#define XAW_TPROP_UNDERLINE (1<<6) +#define XAW_TPROP_OVERSTRIKE (1<<7) +#define XAW_TPROP_SUBSCRIPT (1<<8) +#define XAW_TPROP_SUPERSCRIPT (1<<9) + +/* xlfd attributes */ +#define XAW_TPROP_FOUNDRY (1<<0) +#define XAW_TPROP_FAMILY (1<<1) +#define XAW_TPROP_WEIGHT (1<<2) +#define XAW_TPROP_SLANT (1<<3) +#define XAW_TPROP_SETWIDTH (1<<4) +#define XAW_TPROP_ADDSTYLE (1<<5) +#define XAW_TPROP_PIXELSIZE (1<<6) +#define XAW_TPROP_POINTSIZE (1<<7) +#define XAW_TPROP_RESX (1<<8) +#define XAW_TPROP_RESY (1<<9) +#define XAW_TPROP_SPACING (1<<10) +#define XAW_TPROP_AVGWIDTH (1<<11) +#define XAW_TPROP_REGISTRY (1<<12) +#define XAW_TPROP_ENCODING (1<<13) +struct _XawTextProperty { /* to be extended/modified */ + XrmQuark identifier, code; + unsigned long mask; + XFontStruct *font; + XFontSet fontset; + Pixel foreground, background; + Pixmap foreground_pixmap, background_pixmap; + XrmQuark xlfd; + + unsigned long xlfd_mask; + XrmQuark foundry, family, weight, slant, setwidth, addstyle, pixel_size, + point_size, res_x, res_y, spacing, avgwidth, registry, encoding; + + short underline_position, underline_thickness; +}; + +struct _XawTextPropertyList { + XrmQuark identifier; + Screen *screen; + Colormap colormap; + int depth; + XawTextProperty **properties; + Cardinal num_properties; + XawTextPropertyList *next; +}; + +typedef struct _XawTextPaintStruct XawTextPaintStruct; +struct _XawTextPaintStruct { + XawTextPaintStruct *next; + int x, y, width; + char *text; /* formatted text */ + Cardinal length; /* length of text */ + XawTextProperty *property; + int max_ascent, max_descent; + XmuArea *backtabs; + Boolean highlight; +}; + +typedef struct { + XmuArea *clip, *hightabs; /* clip list */ + XawTextPaintStruct *paint, *bearings; /* drawing information */ +} XawTextPaintList; + +typedef struct { + XtPointer next_extension; + XrmQuark record_type; + long version; + Cardinal record_size; + Bool (*BeginPaint)(Widget); + void (*PreparePaint)(Widget, int, int, + XawTextPosition, XawTextPosition, Bool); + void (*DoPaint)(Widget); + Bool (*EndPaint)(Widget); +} TextSinkExtRec, *TextSinkExt; +#endif + +typedef void (*_XawSinkDisplayTextProc) + (Widget, int, int, XawTextPosition, XawTextPosition, Bool); + +typedef void (*_XawSinkInsertCursorProc) + (Widget, int, int, XawTextInsertState); + +typedef void (*_XawSinkClearToBackgroundProc) + (Widget, int, int, unsigned int, unsigned int); + +typedef void (*_XawSinkFindPositionProc) + (Widget, XawTextPosition, int, int, Bool, XawTextPosition*, int*, int*); + +typedef void (*_XawSinkFindDistanceProc) + (Widget, XawTextPosition, int, XawTextPosition, int*, + XawTextPosition*, int*); + +typedef void (*_XawSinkResolveProc) + (Widget, XawTextPosition, int, int, XawTextPosition*); + +typedef int (*_XawSinkMaxLinesProc) + (Widget, unsigned int); + +typedef int (*_XawSinkMaxHeightProc) + (Widget, int); + +typedef void (*_XawSinkSetTabsProc) + (Widget, int, short*); + +typedef void (*_XawSinkGetCursorBoundsProc) + (Widget, XRectangle*); + +typedef struct _TextSinkClassPart { + _XawSinkDisplayTextProc DisplayText; + _XawSinkInsertCursorProc InsertCursor; + _XawSinkClearToBackgroundProc ClearToBackground; + _XawSinkFindPositionProc FindPosition; + _XawSinkFindDistanceProc FindDistance; + _XawSinkResolveProc Resolve; + _XawSinkMaxLinesProc MaxLines; + _XawSinkMaxHeightProc MaxHeight; + _XawSinkSetTabsProc SetTabs; + _XawSinkGetCursorBoundsProc GetCursorBounds; +#ifndef OLDXAW + TextSinkExt extension; +#endif +} TextSinkClassPart; + +/* Full class record */ +typedef struct _TextSinkClassRec { + ObjectClassPart object_class; + TextSinkClassPart text_sink_class; +} TextSinkClassRec; + +extern TextSinkClassRec textSinkClassRec; + +/* New fields for the TextSink object */ +typedef struct { + /* resources */ + Pixel foreground; /* Foreground color */ + Pixel background; /* Background color */ + + /* private */ + Position *tabs; /* The tab stops as pixel values */ + short *char_tabs; /* The tabs stops as character values */ + int tab_count; /* number of items in tabs */ + +#ifndef OLDXAW + /* more resources */ + Pixel cursor_color; + XawTextPropertyList *properties; + XawTextPaintList *paint; + XtPointer pad[2]; /* for future use and keep binary compatability */ +#endif +} TextSinkPart; + +/* Full instance record */ +typedef struct _TextSinkRec { + ObjectPart object; + TextSinkPart text_sink; +} TextSinkRec; + +/* Semi private routines */ +#ifndef OLDXAW +XawTextPropertyList *XawTextSinkConvertPropertyList +( + String name, + String spec, + Screen *screen, + Colormap Colormap, + int depth + ); + +XawTextProperty *XawTextSinkGetProperty +( + Widget w, + XrmQuark property + ); + +XawTextProperty *XawTextSinkCopyProperty +( + Widget w, + XrmQuark property + ); + +XawTextProperty *XawTextSinkAddProperty +( + Widget w, + XawTextProperty *property + ); + +XawTextProperty *XawTextSinkCombineProperty +( + Widget w, + XawTextProperty *result_in_out, + XawTextProperty *property, + Bool override + ); + +Bool XawTextSinkBeginPaint +( + Widget w + ); + +void XawTextSinkPreparePaint +( + Widget w, + int y, + int line, + XawTextPosition from, + XawTextPosition to, + Bool highlight +); + +void XawTextSinkDoPaint +( + Widget w + ); + +Bool XawTextSinkEndPaint +( + Widget w + ); +#endif + +#define XtInheritDisplayText ((_XawSinkDisplayTextProc)_XtInherit) +#define XtInheritInsertCursor ((_XawSinkInsertCursorProc)_XtInherit) +#define XtInheritClearToBackground ((_XawSinkClearToBackgroundProc)_XtInherit) +#define XtInheritFindPosition ((_XawSinkFindPositionProc)_XtInherit) +#define XtInheritFindDistance ((_XawSinkFindDistanceProc)_XtInherit) +#define XtInheritResolve ((_XawSinkResolveProc)_XtInherit) +#define XtInheritMaxLines ((_XawSinkMaxLinesProc)_XtInherit) +#define XtInheritMaxHeight ((_XawSinkMaxHeightProc)_XtInherit) +#define XtInheritSetTabs ((_XawSinkSetTabsProc)_XtInherit) +#define XtInheritGetCursorBounds ((_XawSinkGetCursorBoundsProc)_XtInherit) + +#endif /* _XawTextSinkP_h */ diff --git a/include/X11/Xaw/TextSrc.h b/include/X11/Xaw/TextSrc.h new file mode 100644 index 0000000..2c65e66 --- /dev/null +++ b/include/X11/Xaw/TextSrc.h @@ -0,0 +1,275 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawTextSrc_h +#define _XawTextSrc_h + +#include <X11/Xaw/Text.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + callback Callback Callback NULL + editType EditType XawTextEditType XawtextRead + enableUndo Undo Boolean False + sourceChanged Changed Boolean False + +*/ + +/* Class record constants */ +extern WidgetClass textSrcObjectClass; + +typedef struct _TextSrcClassRec *TextSrcObjectClass; +typedef struct _TextSrcRec *TextSrcObject; + +typedef enum { + XawstPositions, + XawstWhiteSpace, + XawstEOL, + XawstParagraph, + XawstAll, + XawstAlphaNumeric + } XawTextScanType; + +typedef enum { + Normal, + Selected +} highlightType; + +typedef enum { + XawsmTextSelect, + XawsmTextExtend +} XawTextSelectionMode; + +typedef enum { + XawactionStart, + XawactionAdjust, + XawactionEnd +} XawTextSelectionAction; + +#define XawTextReadError -1 +#define XawTextScanError -1 + +#ifndef OLDXAW +#define XtNenableUndo "enableUndo" +#define XtCUndo "Undo" + +#define XtNsourceChanged "sourceChanged" +#define XtCChanged "Changed" + +#define XtNpropertyCallback "propertyCallback" +#endif + +/* + * Public Functions + */ +_XFUNCPROTOBEGIN + +/* + * Function: + * XawTextSourceRead + * + * Parameters: + * w - TextSrc Object + * pos - position of the text to retreive + * text - text block that will contain returned text + * length - maximum number of characters to read + * + * Description: + * This function reads the source. + * + * Returns: + * The number of characters read into the buffer + */ +XawTextPosition XawTextSourceRead +( + Widget w, + XawTextPosition pos, + XawTextBlock *text_return, + int length + ); + +/* + * Function: + * XawTextSourceReplace + * + * Parameters: + * src - Text Source Object + * startPos - ends of text that will be removed + * endPos - "" + * text - new text to be inserted into buffer at startPos + * + * Description: + * Replaces a block of text with new text + * + * Returns: + * XawEditError or XawEditDone + */ +int XawTextSourceReplace +( + Widget w, + XawTextPosition start, + XawTextPosition end, + XawTextBlock *text + ); + +/* + * Function: + * XawTextSourceScan + * + * Parameters: + * w - TextSrc Object + * position - position to start scanning + * type - type of thing to scan for + * dir - direction to scan + * count - which occurance if this thing to search for + * include - whether or not to include the character found in + * the position that is returned. + * + * Description: + * Scans the text source for the number and type of item specified. + * + * Returns: + * The position of the text + */ +XawTextPosition XawTextSourceScan +( + Widget w, + XawTextPosition position, +#if NeedWidePrototypes + int type, + int dir, + int count, + int include +#else + XawTextScanType type, + XawTextScanDirection dir, + int count, + Boolean include +#endif + ); + +/* + * Function: + * XawTextSourceSearch + * + * Parameters: + * w - TextSource Object + * position - position to start scanning + * dir - direction to search + * text - the text block to search for + * + * Description: + * Searchs the text source for the text block passed. + * + * Returns: + * The position of the text we are searching for or XawTextSearchError + */ +XawTextPosition XawTextSourceSearch +( + Widget w, + XawTextPosition position, +#if NeedWidePrototypes + int dir, +#else + XawTextScanDirection dir, +#endif + XawTextBlock *text + ); + +/* + * Function: + * XawTextSourceConvertSelection + * + * Parameters: + * w - TextSrc object + * selection - current selection atom + * target - current target atom + * type - type to conver the selection to + * value - return value that has been converted + * length - "" + * format - format of the returned value + * + * Returns: + * True if the selection has been converted + */ +Boolean XawTextSourceConvertSelection +( + Widget w, + Atom *selection, + Atom *target, + Atom *type, + XtPointer *value_return, + unsigned long *length_return, + int *format_return + ); + +/* + * Function: + * XawTextSourceSetSelection + * + * Parameters: + * w - TextSrc object + * left - bounds of the selection + * right - "" + * selection - selection atom + * + * Description: + * Allows special setting of the selection. + */ +void XawTextSourceSetSelection +( + Widget w, + XawTextPosition start, + XawTextPosition end, + Atom selection + ); + +_XFUNCPROTOEND + +#endif /* _XawTextSrc_h */ diff --git a/include/X11/Xaw/TextSrcP.h b/include/X11/Xaw/TextSrcP.h new file mode 100644 index 0000000..27514c2 --- /dev/null +++ b/include/X11/Xaw/TextSrcP.h @@ -0,0 +1,258 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawTextSrcP_h +#define _XawTextSrcP_h + +/* + * TextSrc Object Private Data + */ +#include <X11/Xfuncproto.h> + +#include <X11/Xaw/TextSrc.h> +#include <X11/Xaw/TextP.h> /* This source works with the Text widget */ + +_XFUNCPROTOBEGIN + +#ifndef OLDXAW +struct _XawTextAnchor { + XawTextPosition position; + XawTextEntity *entities, *cache; +}; + +#define XAW_TENTF_HIDE 0x0001 +#define XAW_TENTF_READ 0x0002 +#define XAW_TENTF_REPLACE 0x0004 +struct _XawTextEntity { + short type; + short flags; + XawTextEntity *next; + XtPointer data; + XawTextPosition offset; /* from the anchor */ + Cardinal length; + XrmQuark property; +}; +#endif + +#if 0 /* no longer used */ +/* New fields for the TextSrc object class */ +typedef struct { + XtPointer next_extension; + XrmQuark record_type; + long version; + Cardinal record_size; + int (*Input)(); +} TextSrcExtRec, *TextSrcExt; +#endif + +typedef XawTextPosition (*_XawSrcReadProc) + (Widget, XawTextPosition, XawTextBlock*, int); + +typedef int (*_XawSrcReplaceProc) + (Widget, XawTextPosition, XawTextPosition, XawTextBlock*); + +typedef XawTextPosition (*_XawSrcScanProc) + (Widget, XawTextPosition, XawTextScanType, XawTextScanDirection, + int, Bool); + +typedef XawTextPosition (*_XawSrcSearchProc) + (Widget, XawTextPosition, XawTextScanDirection, XawTextBlock*); + +typedef void (*_XawSrcSetSelectionProc) + (Widget, XawTextPosition, XawTextPosition, Atom); + +typedef Boolean (*_XawSrcConvertSelectionProc) + (Widget, Atom*, Atom*, Atom*, XtPointer*, unsigned long*, int*); + +typedef struct _TextSrcClassPart { + _XawSrcReadProc Read; + _XawSrcReplaceProc Replace; + _XawSrcScanProc Scan; + _XawSrcSearchProc Search; + _XawSrcSetSelectionProc SetSelection; + _XawSrcConvertSelectionProc ConvertSelection; +#ifndef OLDXAW + XtPointer extension; +#endif +} TextSrcClassPart; + +/* Full class record */ +typedef struct _TextSrcClassRec { + ObjectClassPart object_class; + TextSrcClassPart textSrc_class; +} TextSrcClassRec; + +extern TextSrcClassRec textSrcClassRec; + +#ifndef OLDXAW +typedef struct _XawTextUndo XawTextUndo; +#endif + +/* New fields for the TextSrc object */ +typedef struct { + /* resources */ + XawTextEditType edit_mode; + XrmQuark text_format; /* 2 formats: FMT8BIT for Ascii + FMTWIDE for ISO 10646 */ +#ifndef OLDXAW + XtCallbackList callback; /* A callback list to call when the + source is changed */ + Boolean changed; + Boolean enable_undo; + + /* private state */ + Boolean undo_state; /* to protect undo manipulation */ + XawTextUndo *undo; + WidgetList text; /* TextWidget's using this source */ + Cardinal num_text; + XtCallbackList property_callback; + XawTextAnchor **anchors; + int num_anchors; + XtPointer pad[1]; /* for future use and keep binary compatability */ +#endif +} TextSrcPart; + +/* Full instance record */ +typedef struct _TextSrcRec { + ObjectPart object; + TextSrcPart textSrc; +} TextSrcRec; + +/* + * Semiprivate declarations of functions used in other modules + */ +char* _XawTextWCToMB +( + Display *display, + wchar_t *wstr, + int *len_in_out + ); + +wchar_t* _XawTextMBToWC +( + Display *display, + char *str, + int *len_in_out + ); + +#ifndef OLDXAW +XawTextAnchor *XawTextSourceAddAnchor +( + Widget source, + XawTextPosition position + ); + +XawTextAnchor *XawTextSourceFindAnchor +( + Widget source, + XawTextPosition position + ); + +XawTextAnchor *XawTextSourceNextAnchor +( + Widget source, + XawTextAnchor *anchor + ); + +XawTextAnchor *XawTextSourcePrevAnchor +( + Widget source, + XawTextAnchor *anchor + ); + +XawTextAnchor *XawTextSourceRemoveAnchor +( + Widget source, + XawTextAnchor *anchor + ); + +Bool XawTextSourceAnchorAndEntity +( + Widget w, + XawTextPosition position, + XawTextAnchor **anchor_return, + XawTextEntity **entity_return + ); + +XawTextEntity *XawTextSourceAddEntity +( + Widget source, + int type, + int flags, + XtPointer data, + XawTextPosition position, + Cardinal length, + XrmQuark property + ); + +void XawTextSourceClearEntities +( + Widget w, + XawTextPosition left, + XawTextPosition right + ); +#endif + +#if 0 /* no longer used */ +typedef XawTextPosition (*_XawTextPositionFunc)(); +#endif + +#define XtInheritInput ((_XawTextPositionFunc)_XtInherit) +#define XtInheritRead ((_XawSrcReadProc)_XtInherit) +#define XtInheritReplace ((_XawSrcReplaceProc)_XtInherit) +#define XtInheritScan ((_XawSrcScanProc)_XtInherit) +#define XtInheritSearch ((_XawSrcSearchProc)_XtInherit) +#define XtInheritSetSelection ((_XawSrcSetSelectionProc)_XtInherit) +#define XtInheritConvertSelection ((_XawSrcConvertSelectionProc)_XtInherit) +#if 0 +#define XtTextSrcExtVersion 1 +#define XtTextSrcExtTypeString "XT_TEXTSRC_EXT" +#endif + +_XFUNCPROTOEND + +#endif /* _XawTextSrcP_h */ diff --git a/include/X11/Xaw/Tip.h b/include/X11/Xaw/Tip.h new file mode 100644 index 0000000..5400234 --- /dev/null +++ b/include/X11/Xaw/Tip.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1999 by The XFree86 Project, Inc. + * + * 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 XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + * + * Author: Paulo César Pereira de Andrade + */ + +#ifndef _XawTip_h +#define _XawTip_h + +/* + * Tip Widget + */ + +#include <X11/Xaw/Simple.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + backgroundPixmap BackgroundPixmap Pixmap XtUnspecifiedPixmap + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + bottomMargin VerticalMargins Dimension 2 + destroyCallback Callback XtCallbackList NULL + displayList DisplayList XawDisplayList* NULL + font Font XFontStruct* XtDefaultFont + foreground Foreground Pixel XtDefaultForeground + height Height Dimension text height + leftMargin HorizontalMargins Dimension 6 + rightMargin HorizontalMargins Dimension 6 + timeout Timeout Int 500 + topMargin VerticalMargins Dimension 2 + width Width Dimension text width + x Position Position 0 + y Position Position 0 + +*/ + +typedef struct _TipClassRec *TipWidgetClass; +typedef struct _TipRec *TipWidget; + +extern WidgetClass tipWidgetClass; + +#define XtNbottomMargin "bottomMargin" +#define XawNdisplayList "displayList" +#define XtNencoding "encoding" +#define XtNleftMargin "leftMargin" +#define XtNrightMargin "rightMargin" +#define XtNtimeout "timeout" +#define XtNtopMargin "topMargin" +#define XtNtip "tip" + +#define XawCDisplayList "DisplayList" +#define XtCHorizontalMargins "HorizontalMargins" +#define XtCTimeout "Timeout" +#define XtCVerticalMargins "VerticalMargins" +#define XtCTip "Tip" + +#define XawRDisplayList "XawDisplayList" + +/* + * Public Functions + */ +/* + * Function: + * XawTipEnable + * + * Parameters: + * w - widget + * + * Description: + * Enables the tip event handler for this widget. + */ +void XawTipEnable +( + Widget w + ); + +/* + * Function: + * XawTipEnable + * + * Parameters: + * w - widget + * + * Description: + * Disables the tip event handler for this widget. + */ +void XawTipDisable +( + Widget w + ); + +#endif /* _XawTip_h */ diff --git a/include/X11/Xaw/TipP.h b/include/X11/Xaw/TipP.h new file mode 100644 index 0000000..48c688b --- /dev/null +++ b/include/X11/Xaw/TipP.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 1999 by The XFree86 Project, Inc. + * + * 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 XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + * + * Author: Paulo César Pereira de Andrade + */ + +#ifndef _XawTipP_h +#define _XawTipP_h + +#include <X11/Xaw/Tip.h> +#include <X11/CoreP.h> +#include <X11/Xaw/XawInit.h> + +typedef struct { + XtPointer extension; +} TipClassPart; + +typedef struct _TipClassRec { + CoreClassPart core_class; + TipClassPart tip_class; +} TipClassRec; + +extern TipClassRec tipClassRec; + +typedef struct _TipPart { + /* resources */ + Pixel foreground; + XFontStruct *font; + XFontSet fontset; + Dimension top_margin; + Dimension bottom_margin; + Dimension left_margin; + Dimension right_margin; + int backing_store; + int timeout; + XawDisplayList *display_list; + + /* private */ + GC gc; + XtIntervalId timer; + String label; + Boolean international; + unsigned char encoding; + XtPointer pad[4]; +} TipPart; + +typedef struct _TipRec { + CorePart core; + TipPart tip; +} TipRec; + +#endif /* _XawTipP_h */ diff --git a/include/X11/Xaw/Toggle.h b/include/X11/Xaw/Toggle.h new file mode 100644 index 0000000..f6c6b97 --- /dev/null +++ b/include/X11/Xaw/Toggle.h @@ -0,0 +1,179 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +/* + * ToggleP.h - Private definitions for Toggle widget + * + * Author: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + * + * Date: January 12, 1989 + */ + +#ifndef _XawToggle_h +#define _XawToggle_h + +#include <X11/Xaw/Command.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + radioGroup RadioGroup Widget NULL + + radioData RadioData Pointer (XPointer) Widget ++ + state State Boolean Off + + background Background Pixel XtDefaultBackground + bitmap Pixmap Pixmap None + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + callback Callback Pointer NULL + cursor Cursor Cursor None + destroyCallback Callback Pointer NULL + displayList DisplayList XawDisplayList* NULL + font Font XFontStructx* XtDefaultFont + foreground Foreground Pixel XtDefaultForeground + height Height Dimension text height + highlightThickness Thickness Dimension 2 + insensitiveBorder Insensitive Pixmap Gray + internalHeight Height Dimension 2 + internalWidth Width Dimension 4 + justify Justify XtJustify XtJustifyCenter + label Label String NULL + mappedWhenManaged MappedWhenManaged Boolean True + resize Resize Boolean True + sensitive Sensitive Boolean True + width Width Dimension text width + x Position Position 0 + y Position Position 0 + ++ To use the toggle as a radio toggle button, set this resource to point to + any other widget in the radio group. + +++ This is the data returned from a call to XtToggleGetCurrent, by default + this is set to the name of toggle widget. + +*/ + +/* + * These should be in StringDefs.h but aren't so we will define + * them here if they are needed + */ +#define XtCWidget "Widget" +#define XtCState "State" +#define XtCRadioGroup "RadioGroup" +#define XtCRadioData "RadioData" + +#ifndef _XtStringDefs_h_ +#define XtRWidget "Widget" +#endif + +#define XtNstate "state" +#define XtNradioGroup "radioGroup" +#define XtNradioData "radioData" + +extern WidgetClass toggleWidgetClass; + +typedef struct _ToggleClassRec *ToggleWidgetClass; +typedef struct _ToggleRec *ToggleWidget; + +/* + * Public Functions + */ + +_XFUNCPROTOBEGIN + +/* + * Function: + * XawToggleChangeRadioGroup + * + * Parameters: + * w - toggle widget to change lists + * radio_group - any widget in the new list + * + * Description: + * Allows a toggle widget to change radio lists. + */ +void XawToggleChangeRadioGroup +( + Widget w, + Widget radio_group + ); + +/* + * Function: + * XawToggleGetCurrent + * + * Parameters: + * radio_group - any toggle widget in the toggle list + * + * Description: + * Returns the RadioData associated with the toggle + * widget that is currently active in a toggle list. + * Returns: + * The XtNradioData associated with the toggle widget + */ + +XtPointer XawToggleGetCurrent +( + Widget radio_group + ); + +/* + * Function: + * XawToggleSetCurrent + * + * Parameters: + * radio_group - any toggle widget in the toggle list + * radio_data - radio data of the toggle widget to set + * + * Description: + * Sets the Toggle widget associated with the radio_data specified. + */ +void XawToggleSetCurrent +( + Widget radio_group, + XtPointer radio_data + ); + +/* + * Function: + * XawToggleUnsetCurrent + * + * Parameters: + * radio_group - any toggle widget in the toggle list + * + * Description: + * Unsets all Toggles in the radio_group specified. + */ +void XawToggleUnsetCurrent +( + Widget radio_group + ); + +_XFUNCPROTOEND + +#endif /* _XawToggle_h */ diff --git a/include/X11/Xaw/ToggleP.h b/include/X11/Xaw/ToggleP.h new file mode 100644 index 0000000..a816598 --- /dev/null +++ b/include/X11/Xaw/ToggleP.h @@ -0,0 +1,92 @@ +/* + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* + * Author: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + * + * Date: January 12, 1989 + * + */ + +#ifndef _XawToggleP_h +#define _XawToggleP_h + +#include <X11/Xaw/Toggle.h> +#include <X11/Xaw/CommandP.h> + +/* + * Toggle Widget Private Data + */ +#define streq(a, b) (strcmp((a), (b)) == 0) + +typedef struct _RadioGroup { + struct _RadioGroup *prev, *next; /* Pointers to other elements in group */ + Widget widget; /* Widget corrosponding to this element */ +} RadioGroup; + +/* New fields for the Toggle widget class */ +typedef struct _ToggleClass { + XtActionProc Set; + XtActionProc Unset; + XtPointer extension; +} ToggleClassPart; + +/* class record declaration */ +typedef struct _ToggleClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + LabelClassPart label_class; + CommandClassPart command_class; + ToggleClassPart toggle_class; +} ToggleClassRec; + +extern ToggleClassRec toggleClassRec; + +/* New fields for the Toggle widget */ +typedef struct { + /* resources */ + Widget widget; + XtPointer radio_data; + + /* private */ + RadioGroup *radio_group; +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} TogglePart; + +/* Full widget declaration */ +typedef struct _ToggleRec { + CorePart core; + SimplePart simple; + LabelPart label; + CommandPart command; + TogglePart toggle; +} ToggleRec; + +#endif /* _XawToggleP_h */ diff --git a/include/X11/Xaw/Tree.h b/include/X11/Xaw/Tree.h new file mode 100644 index 0000000..1747a78 --- /dev/null +++ b/include/X11/Xaw/Tree.h @@ -0,0 +1,135 @@ +/* + * + +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1989 Prentice Hall + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation. + * + * Prentice Hall and the authors disclaim all warranties with regard + * to this software, including all implied warranties of merchantability and + * fitness. In no event shall Prentice Hall or the authors be liable + * for any special, indirect or cosequential damages or any damages whatsoever + * resulting from loss of use, data or profits, whether in an action of + * contract, negligence or other tortious action, arising out of or in + * connection with the use or performance of this software. + * + * Authors: Jim Fulton, MIT X Consortium, + * based on a version by Douglas Young, Prentice Hall + * + * This widget is based on the Tree widget described on pages 397-419 of + * Douglas Young's book "The X Window System, Programming and Applications + * with Xt OSF/Motif Edition." The layout code has been rewritten to use + * additional blank space to make the structure of the graph easier to see + * as well as to support vertical trees. + */ + +#ifndef _XawTree_h +#define _XawTree_h + +#include <X11/Xmu/Converters.h> + +/****************************************************************************** + * + * Tree Widget (subclass of ConstraintClass) + * + ****************************************************************************** + * + * Parameters: + * + * Name Class Type Default + * ---- ----- ---- ------- + * + * autoReconfigure AutoReconfigure Boolean FALSE + * background Background Pixel XtDefaultBackground + * foreground Foreground Pixel XtDefaultForeground + * gravity Gravity XtGravity West + * hSpace HSpace Dimension 20 + * lineWidth LineWidth Dimension 0 + * vSpace VSpace Dimension 6 + * + * + * Constraint Resources attached to children: + * + * treeGC TreeGC GC NULL + * treeParent TreeParent Widget NULL + * + * + *****************************************************************************/ + + /* new instance field names */ +#ifndef _XtStringDefs_h_ +#define XtNhSpace "hSpace" +#define XtNvSpace "vSpace" +#define XtCHSpace "HSpace" +#define XtCVSpace "VSpace" +#endif + +#define XtNautoReconfigure "autoReconfigure" +#define XtNlineWidth "lineWidth" +#define XtNtreeGC "treeGC" +#define XtNtreeParent "treeParent" +#define XtNgravity "gravity" + + /* new class field names */ +#define XtCAutoReconfigure "AutoReconfigure" +#define XtCLineWidth "LineWidth" +#define XtCTreeGC "TreeGC" +#define XtCTreeParent "TreeParent" +#define XtCGravity "Gravity" + +#define XtRGC "GC" + +#ifndef OLDXAW +#ifndef XawNdisplayList +#define XawNdisplayList "displayList" +#endif + +#ifndef XawCDisplayList +#define XawCDisplayList "DisplayList" +#endif + +#ifndef XawRDisplayList +#define XawRDisplayList "XawDisplayList" +#endif +#endif + /* external declarations */ +extern WidgetClass treeWidgetClass; + +typedef struct _TreeClassRec *TreeWidgetClass; +typedef struct _TreeRec *TreeWidget; + +_XFUNCPROTOBEGIN + +void XawTreeForceLayout +( + Widget tree + ); + +_XFUNCPROTOEND + +#endif /* _XawTree_h */ diff --git a/include/X11/Xaw/TreeP.h b/include/X11/Xaw/TreeP.h new file mode 100644 index 0000000..01d2bdc --- /dev/null +++ b/include/X11/Xaw/TreeP.h @@ -0,0 +1,137 @@ +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1989 Prentice Hall + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation. + * + * Prentice Hall and the authors disclaim all warranties with regard + * to this software, including all implied warranties of merchantability and + * fitness. In no event shall Prentice Hall or the authors be liable + * for any special, indirect or cosequential damages or any damages whatsoever + * resulting from loss of use, data or profits, whether in an action of + * contract, negligence or other tortious action, arising out of or in + * connection with the use or performance of this software. + * + * Authors: Jim Fulton, MIT X Consortium, + * based on a version by Douglas Young, Prentice Hall + * + * This widget is based on the Tree widget described on pages 397-419 of + * Douglas Young's book "The X Window System, Programming and Applications + * with Xt OSF/Motif Edition." The layout code has been rewritten to use + * additional blank space to make the structure of the graph easier to see + * as well as to support vertical trees. + */ + +#ifndef _XawTreeP_h +#define _XawTreeP_h + +#include <X11/Xaw/Tree.h> + +typedef struct _TreeClassPart { + XtPointer extension; +} TreeClassPart; + +typedef struct _TreeClassRec { + CoreClassPart core_class; + CompositeClassPart composite_class; + ConstraintClassPart constraint_class; + TreeClassPart tree_class; +} TreeClassRec; + +extern TreeClassRec treeClassRec; + +typedef struct { + /* fields available through resources */ + Dimension hpad; /* hSpace/HSpace */ + Dimension vpad; /* vSpace/VSpace */ + Dimension line_width; /* lineWidth/LineWidth */ + Pixel foreground; /* foreground/Foreground */ + XtGravity gravity; /* gravity/Gravity */ + Boolean auto_reconfigure; /* autoReconfigure/AutoReconfigure */ + /* private fields */ + GC gc; /* used to draw lines */ + Widget tree_root; /* hidden root off all children */ + Dimension *largest; /* list of largest per depth */ + int n_largest; /* number of elements in largest */ + Dimension maxwidth, maxheight; /* for shrink wrapping */ +#ifndef OLDXAW + XawDisplayList *display_list; + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} TreePart; + + +typedef struct _TreeRec { + CorePart core; + CompositePart composite; + ConstraintPart constraint; + TreePart tree; +} TreeRec; + + +/* + * structure attached to all children + */ +typedef struct _TreeConstraintsPart { + /* resources */ + Widget parent; /* treeParent/TreeParent */ + GC gc; /* treeGC/TreeGC */ + /* private data */ + Widget *children; + int n_children; + int max_children; + Dimension bbsubwidth, bbsubheight; /* bounding box of sub tree */ + Dimension bbwidth, bbheight; /* bounding box including node */ + Position x, y; +#ifndef OLDXAW + XtPointer pad[2]; /* leave some space for future optimizations, and + * keep binary compatability + */ +#endif +} TreeConstraintsPart; + +typedef struct _TreeConstraintsRec { + TreeConstraintsPart tree; +} TreeConstraintsRec, *TreeConstraints; + + +/* + * useful macros + */ + +#define TREE_CONSTRAINT(w) \ + ((TreeConstraints)((w)->core.constraints)) + +#define TREE_INITIAL_DEPTH 10 /* for allocating largest array */ +#define TREE_HORIZONTAL_DEFAULT_SPACING 20 +#define TREE_VERTICAL_DEFAULT_SPACING 6 + +#endif /* _XawTreeP_h */ + + + diff --git a/include/X11/Xaw/VendorEP.h b/include/X11/Xaw/VendorEP.h new file mode 100644 index 0000000..b91f10a --- /dev/null +++ b/include/X11/Xaw/VendorEP.h @@ -0,0 +1,81 @@ +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of OMRON not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. OMRON makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Seiji Kuwari OMRON Corporation + * kuwa@omron.co.jp + * kuwa%omron.co.jp@uunet.uu.net + */ + +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifndef _VendorEP_h +#define _VendorEP_h + +#include <X11/Xaw/XawImP.h> + +typedef struct { + XtPointer extension; +} XawVendorShellExtClassPart; + +typedef struct _VendorShellExtClassRec { + ObjectClassPart object_class; + XawVendorShellExtClassPart vendor_shell_ext_class; +} XawVendorShellExtClassRec; + +typedef struct { + Widget parent; + XawImPart im; + XawIcPart ic; +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} XawVendorShellExtPart; + +typedef struct XawVendorShellExtRec { + ObjectPart object; + XawVendorShellExtPart vendor_ext; +} XawVendorShellExtRec, *XawVendorShellExtWidget; + +#endif /* _VendorEP_h */ diff --git a/include/X11/Xaw/Viewport.h b/include/X11/Xaw/Viewport.h new file mode 100644 index 0000000..36fab44 --- /dev/null +++ b/include/X11/Xaw/Viewport.h @@ -0,0 +1,118 @@ +/************************************************************ + +Copyright 1987, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +********************************************************/ + +#ifndef _XawViewport_h +#define _XawViewport_h + +#include <X11/Xaw/Form.h> +#include <X11/Xaw/Reports.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + allowHoriz Boolean Boolean False + allowVert Boolean Boolean False + background Background Pixel XtDefaultBackground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + destroyCallback Callback Pointer NULL + forceBars Boolean Boolean False + height Height Dimension 0 + mappedWhenManaged MappedWhenManaged Boolean True + reportCallback ReportCallback Pointer NULL + sensitive Sensitive Boolean True + useBottom Boolean Boolean False + useRight Boolean Boolean False + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +#ifndef _XtStringDefs_h_ +#define XtNforceBars "forceBars" +#define XtNallowHoriz "allowHoriz" +#define XtNallowVert "allowVert" +#define XtNuseBottom "useBottom" +#define XtNuseRight "useRight" +#endif + +extern WidgetClass viewportWidgetClass; + +typedef struct _ViewportClassRec *ViewportWidgetClass; +typedef struct _ViewportRec *ViewportWidget; + +_XFUNCPROTOBEGIN + +void XawViewportSetLocation +( + Widget gw, +#if NeedWidePrototypes + double xoff, + double yoff +#else + float xoff, + float yoff +#endif + ); + +void XawViewportSetCoordinates +( + Widget gw, +#if NeedWidePrototypes + int x, + int y +#else + Position x, + Position y +#endif + ); + +_XFUNCPROTOEND + +#endif /* _XawViewport_h */ diff --git a/include/X11/Xaw/ViewportP.h b/include/X11/Xaw/ViewportP.h new file mode 100644 index 0000000..2aeb8a5 --- /dev/null +++ b/include/X11/Xaw/ViewportP.h @@ -0,0 +1,107 @@ +/* + * Private declarations for ViewportWidgetClass + */ + +/************************************************************ + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +********************************************************/ + +#ifndef _ViewportP_h +#define _ViewportP_h + +#include <X11/Xaw/Viewport.h> +#include <X11/Xaw/FormP.h> + +typedef struct { + XtPointer extension; +} ViewportClassPart; + +typedef struct _ViewportClassRec { + CoreClassPart core_class; + CompositeClassPart composite_class; + ConstraintClassPart constraint_class; + FormClassPart form_class; + ViewportClassPart viewport_class; +} ViewportClassRec; + +extern ViewportClassRec viewportClassRec; + +typedef struct _ViewportPart { + /* resources */ + Boolean forcebars; /* Whether we should always display + the selected scrollbars */ + Boolean allowhoriz; /* Whether we allow horizontal scrollbars */ + Boolean allowvert; /* Whether we allow vertical scrollbars */ + Boolean usebottom; /* True if horiz bars appear at bottom */ + Boolean useright; /* True if vert bars appear at right */ + XtCallbackList report_callbacks;/* when size/position changes */ + + /* private */ + Widget clip, child; /* The clipping and (scrolled) child widgets */ + Widget horiz_bar, vert_bar; /* What scrollbars we currently have */ +#ifndef OLDXAW + XtPointer pad[4]; /* for future use and keep binary compatability */ +#endif +} ViewportPart; + +typedef struct _ViewportRec { + CorePart core; + CompositePart composite; + ConstraintPart constraint; + FormPart form; + ViewportPart viewport; +} ViewportRec; + +typedef struct { + Bool reparented; /* True if child has been re-parented */ +} ViewportConstraintsPart; + +typedef struct _ViewportConstraintsRec { + FormConstraintsPart form; + ViewportConstraintsPart viewport; +} ViewportConstraintsRec, *ViewportConstraints; + +#endif /* _ViewportP_h */ diff --git a/include/X11/Xaw/XawImP.h b/include/X11/Xaw/XawImP.h new file mode 100644 index 0000000..a03eef6 --- /dev/null +++ b/include/X11/Xaw/XawImP.h @@ -0,0 +1,210 @@ +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of OMRON not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. OMRON makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Seiji Kuwari OMRON Corporation + * kuwa@omron.co.jp + * kuwa%omron.co.jp@uunet.uu.net + */ + +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifndef _XawImP_h +#define _XawImP_h + +#define XtNinputMethod "inputMethod" +#define XtCInputMethod "InputMethod" +#define XtNpreeditType "preeditType" +#define XtCPreeditType "PreeditType" +#define XtNopenIm "openIm" +#define XtCOpenIm "OpenIm" +#define XtNsharedIc "sharedIc" +#define XtCSharedIc "SharedIc" + +#include <X11/Xaw/Text.h> + +#define CIICFocus (1 << 0) +#define CIFontSet (1 << 1) +#define CIFg (1 << 2) +#define CIBg (1 << 3) +#define CIBgPixmap (1 << 4) +#define CICursorP (1 << 5) +#define CILineS (1 << 6) + +typedef struct _XawImPart { + XIM xim; + XrmResourceList resources; + Cardinal num_resources; + Boolean open_im; + Boolean initialized; + Dimension area_height; + String input_method; + String preedit_type; +} XawImPart; + +typedef struct _XawIcTablePart { + Widget widget; + XIC xic; + XIMStyle input_style; + unsigned long flg; + unsigned long prev_flg; + Boolean ic_focused; + XFontSet font_set; + Pixel foreground; + Pixel background; + Pixmap bg_pixmap; + XawTextPosition cursor_position; + unsigned long line_spacing; + Boolean openic_error; + struct _XawIcTablePart *next; +} XawIcTablePart, *XawIcTableList; + +typedef struct _XawIcPart { + XIMStyle input_style; + Boolean shared_ic; + XawIcTableList shared_ic_table; + XawIcTableList current_ic_table; + XawIcTableList ic_table; +} XawIcPart; + +typedef struct _contextDataRec { + Widget parent; + Widget ve; +} contextDataRec; + +typedef struct _contextErrDataRec { + Widget widget; + XIM xim; +} contextErrDataRec; + +void _XawImResizeVendorShell +( + Widget w + ); + +Dimension _XawImGetShellHeight +( + Widget w +); + +void _XawImRealize +( + Widget w + ); + +void _XawImInitialize +( + Widget w, + Widget ext + ); + +void _XawImReconnect +( + Widget w + ); + +void _XawImRegister +( + Widget w + ); + +void _XawImUnregister +( + Widget w + ); + +void _XawImSetValues +( + Widget w, + ArgList args, + Cardinal num_args + ); + +void _XawImSetFocusValues +( + Widget w, + ArgList args, + Cardinal num_args +); + +void _XawImUnsetFocus +( + Widget w + ); + +int _XawImWcLookupString +( + Widget w, + XKeyPressedEvent *event, + wchar_t *buffer_return, + int bytes_buffer, + KeySym *keysym_return + ); + +int _XawLookupString +( + Widget w, + XKeyEvent *event, + char *buffer_return, + int buffer_size, + KeySym *keysym_return + ); + +int _XawImGetImAreaHeight +( + Widget w + ); + +void _XawImCallVendorShellExtResize +( + Widget w + ); + +void _XawImDestroy +( + Widget w, + Widget ext + ); + +#endif /* _XawImP_h */ diff --git a/include/X11/Xaw/XawInit.h b/include/X11/Xaw/XawInit.h new file mode 100644 index 0000000..73226b2 --- /dev/null +++ b/include/X11/Xaw/XawInit.h @@ -0,0 +1,62 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group +Copyright 2003-2004 Roland Mainz <roland.mainz@nrubsig.org> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ +#ifndef _XawInit_h +#define _XawInit_h + +#define XawVendor XVENDORNAMESHORT + +#ifdef OLDXAW +#define XawVersion 6700002L +#else +#define XawVersion 7000002L + +typedef struct _XawDL XawDisplayList; +#endif /* OLDXAW */ + +#include <X11/Intrinsic.h> +#include <X11/Xfuncproto.h> + +_XFUNCPROTOBEGIN + +void XawInitializeWidgetSet(void); +#ifndef OLDXAW +void XawInitializeDefaultConverters(void); +#endif + +extern Widget XawOpenApplication( + XtAppContext *app_context_return, + Display *dpy, + Screen *screen, + String application_name, + String application_class, + WidgetClass widget_class, + int *argc, + String *argv +); + +_XFUNCPROTOEND + +#endif /* _XawInit_h */ diff --git a/man/Makefile.am b/man/Makefile.am new file mode 100644 index 0000000..1d67cb4 --- /dev/null +++ b/man/Makefile.am @@ -0,0 +1,41 @@ +# +# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. +# +# 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 (including the next +# paragraph) 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. +# + +libmandir = $(LIB_MAN_DIR) + +libman_PRE = Xaw.man + +libman_DATA = $(libman_PRE:man=@LIB_MAN_SUFFIX@) + +EXTRA_DIST = $(libman_PRE) + +CLEANFILES = $(libman_DATA) + +SUFFIXES = .$(LIB_MAN_SUFFIX) .man + +# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure +MAN_SUBSTS += -e 's|__docdir__|$(docdir)|g' + +.man.$(LIB_MAN_SUFFIX): + $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ + diff --git a/man/Xaw.man b/man/Xaw.man new file mode 100644 index 0000000..55caefe --- /dev/null +++ b/man/Xaw.man @@ -0,0 +1,629 @@ +.\" +.\" Copyright (c) 1999 by The XFree86 Project, Inc. +.\" +.\" 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 XFREE86 PROJECT 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. +.\" +.\" Except as contained in this notice, the name of the XFree86 Project shall +.\" not be used in advertising or otherwise to promote the sale, use or other +.\" dealings in this Software without prior written authorization from the +.\" XFree86 Project. +.\" +.\" Author: Paulo César Pereira de Andrade +.\" +.de EX +.sp +.nf +.ft CW +.. +.de EE +.ft R +.fi +.sp +.. +.de TQ +.\".br +.ns +.TP \\$1 +.. +.TH Xaw __libmansuffix__ __vendorversion__ +.SH NAME + Xaw \- X Athena Widgets +.SH DESCRIPTION +.B Xaw +is a widget set based on the X Toolkit Intrinsics (Xt) Library. This +release by the X.Org Foundation includes additions and modifications +originally made for The XFree86 Project, Inc. This manual page describes +these changes as well as some of the common interfaces between its version +and the previous X Consortium release (Xaw6). +.PP +The bulk of the Xaw documentation is located in the API specification +which may be installed in __docdir__, or found on the X.Org website. +.SH ACTIONS +All of the \fIXaw\fR widgets now have the additional translations +.B call-proc, declare, get-values +and \fBset-values\fP. The syntax for these actions is: +.PP +.I action-name \fP(\fIboolean-expression\fP, \fIarguments\fP) +.PP +\fBAction-name\fP is one of \fIcall-proc\fP, \fIdeclare\fP, +\fIget-values\fP or \fIset-values\fP. +.PP +\fBBoolean-expression\fP is composed with the operators \fI|\fR (or), \fI&\fR +(and), \fI^\fR (xor), and \fI~\fR (not). The operands can be a variable name, +which starts with a \fI$\fR; a resource name without the bindings \fI.\fP +or \fI*\fP; or a constant name, including \fImine\fP (event->xany.window +== XtWindow(widget)), \fIfaked\fP (event->xany.send_event != 0), \fItrue\fP (1) +and \fIfalse\fP (0). +.PP +\fBArguments\fP are self-explanatory; when starting with a \fI$\fP they name +a variable, otherwise, they indicate a resource name. +.TP 8 +.B call-proc \fP(\fIboolean-expression\fP, \fIprocedure-name\fP) +This action allows the evaluation of a boolean expression in the first +parameter before calling a action procedure. The procedure is only called +if the expression evaluates as true. Example: +.EX +call-proc("$inside & $pressed", notify) +.EE +.TP 8 +.B declare \fP(\fIboolean-expression\fP, \fIvariable\fP, \fIvalue\fP, ...) +This action is used to create new variables or change their values. Any +number of variable-value tuples may be specified. Example: +.EX +declare(1, $pressed, 1) +.EE +.TP 8 +.B get-values \fP(\fIboolean-expression\fP, \fIvariable\fP, \fIvalue\fP, ...) +This action reads a widget resource value into a variable. Any number of +variable-value tuples may be specified. Example: +.EX +get-values(1, $fg, foreground, $bg, background) +.EE +.TP 8 +.B set-values \fP(\fIboolean-expression\fP, \fIvariable\fP, \fIvalue\fP, ...) +This action sets a widget resource to the given value, which may be a +variable. Any number of variable-value tuples may be specified. Example: +.EX +set-values(1, foreground, $bg, background, $fg) +.EE +.PP +Here is a sample translation to make a label widget behave like a button: +.PP +.nf +<Map>: get-values(1, $fg, foreground, $bg, background)\en\e +<Btn1Down>: set-values(1, foreground, yellow, background, gray30)\en\e +<Btn1Up>: set-values(1, foreground, $fg, background, $bg) +.fi +.SH DISPLAY LISTS +All of the \fBXaw\fP widgets have now the additional resource +\fIdisplayList\fP. This resource allows drawing the widget decorations +using commands embedded in a resource string. The displayList resource has +the syntax: +.PP +\fI[class-name:]function-name arguments[[{;\en}]...]\fP +.PP +\fBClass-name\fP is any registered set of functions to draw in the widget. +Currently the only existing class is \fIxlib\fP, which provides access to +the Xlib drawing primitives. +.PP +\fBFunction-name\fP is the drawing or configuration function to be called, +described bellow. +.PP +\fBArguments\fP may be anything suitable to the displayList function being +called. When the function requires a coordinate, the syntax is +\fI{+-}<integer>\fP or \fI<integer>/<integer>\fP. Examples: +.nf + +0,+0 top, left + -0,-0 bottom, right + -+10,-+10 bottom+10, right+10 + +0,1/2 left, vertical-center +.fi +.TP 8 +.B arc-mode \fPmode +Sets the arc mode. Accepted \fImode\fPs are "pieslice" and "chord", which +set the arc to ArcPieSlice or ArcChord, respectively. Example: +.EX +arc-mode chord +.EE +.TP 8 +.B bg \fPcolor-spec +.TQ +.B background \fPcolor-spec +Sets the background color. \fIcolor-spec\fP must a valid color +specification. Example: +.EX +background red +.EE +.TP 8 +.B cap-style \fPstyle +Sets the cap style. Accepted \fIstyle\fPs are "notlast", "butt", "round", +and "projecting", which set the cap style to CapNotLast, CapBut, CapRound +or CapProjecting, respectively. Example: +.EX +cap-style round +.EE +.TP 8 +.B clip-mask \fPpixmap-spec +Sets the pixmap for the clip mask. Requires a pixmap parameter, as +described in the \fBPIXMAPS\fP section below. Example: +.EX +clip-mask xlogo11 +.EE +.TP 8 +.B clip-origin \fPx,y +Sets the clip x and y origin. Requires two arguments, the x and y +coordinates. Example: +.EX +clip-origin 10,10 +.EE +.TP 8 +.B clip-rects \fPx1,y1,x2,y2 [...,xn,yn] +.TQ +.B clip-rectangles \fPx1,y1,x2,y2 [...,xn,yn] +Sets a list of rectangles to the clip mask. The number of arguments must +be a multiple of four. The arguments are coordinates. The parser +calculates the width and height of the rectangles. Example: +.EX +clip-rects 0,0,10,20, 20,10,30,30 +.EE +.TP 8 +.B coord-mode \fPmode +Changes the coord mode for \fIfill-polygon\fP, \fIdraw-lines\fP, and +\fIdraw-points\fP. Accepted parameters are "modeorigin" and "previous", +that sets the coord mode to CoordModeOrigin or CoordModePrevious, +respectively. Example: +.EX +coord-mode previous +.EE +.TP 8 +.B copy-area \fP{pixmap-spec|.},dstx,dsty[,x2,y2,srcx,srcy] +Calls XCopyArea. The character \fI.\fP means copy the window contents; +pixmap-spec is as defined in the \fBPIXMAPS\fP section below. \fIX2\fP and +\fIy2\fP are the coordinates of the end copy, not the width and height; if +not defined, the parser calculates them. \fIsrc_x\fP and \fIsrc_y\fP +default to zero. Example: +.EX +copy-area Term,10,10 +.EE +.TP 8 +.B copy-plane \fP{pixmap-spec|.},dstx,dsty[,x2,y2,srcx,srcy,plane] +Calls XCopyPlane. The character \fI.\fP means copy the window contents; +pixmap-spec is as defined in the \fBPIXMAPS\fP section below. \fIX2\fP and +\fIy2\fP are the coordinates of the end copy, not the width and height; if +not defined, the parser calculates them. \fIsrc_x\fP and \fIsrc_y\fP +default to zero. \fIPlane\fP defaults to one. Example: +.EX +copy-plane star,10,10 +.EE +.TP 8 +.B dashes \fPi1[...,in] +Sets the dashes for line drawing. Accepts up to 127 arguments. Example: +.EX +dashes 3,7 9,10 +.EE +.TP 8 +.B draw-arc \fPx1,y1,x2,y2[,start-angle,end-angle] +Draws an arc. The four first arguments are the rectangle enclosing the +arc. The two remaining arguments, if specified, are the start and end +angle, in degrees. Example: +.EX +draw-arc +0,+0,-1,-1,0,90 +.EE +.TP 8 +.B draw-rect \fPx1,y1,x2,y2 +.TQ +.B draw-rectangle \fPx1,y1,x2,y2 +Draws a rectangle. Requires four arguments, which are the start and end +coordinate pairs. Example: +.EX +draw-rect +1,+1,-5,-5 +.EE +.TP 8 +.B draw-string \fPx,y,"string" +Draws a text string. Requires three arguments, a x coordinate, a y +coordinate, and a string. Strings that have white space can be quoted with +the \fI"\fP character; the backslash character \fI\e\fP can also be used, +but it will be necessary escape it twice. Example: +.EX + draw-string 10,10, "Hello world!"\fP +.EE +.TP 8 +.B exposures \fPboolean +Sets graphics exposures in the GC. Allowed parameters are a integer or the +strings "true", "false", "on" and "off". Example: +.EX +exposures true +.EE +.TP 8 +.B fill-arc \fPx1,y1,x2,y2[,start-angle,end-angle] +Like \fIdraw-arc\fP, but fills the contents of the arc with the currently +selected foreground. Example: +.EX +fill-arc +0,+0,-1,-1,0,180 +.EE +.TP 8 +.B fill-poly \fPx1,y1 [...,xn,yn] +.TQ +.B fill-polygon \fPx1,y1 [...,xn,yn] +Like \fIdraw-lines\fP, but fills the enclosed polygon and joins the first +and last point, if they are not at the same position. Example: +.EX +fill-poly +0,+10, +10,+20, +30,+0 +.EE +.TP +.B fill-rect \fPx1,y1,x2,y2 +.TQ +.B fill-rectangle \fPx1,y1,x2,y2 +Like \fIdraw-rect\fP, but fills the contents of the rectangle with the +selected foreground color. Example: +.EX +fill-rect +10,+10,-20,-20 +.EE +.TP 8 +.B fill-rule \fPrule +Sets the fill rule. Accepted parameters are "evenodd" and "winding", which +set the fill rule to EvenOddRule or WindingRule, respectively. Example: +.EX +fill-rule winding +.EE +.TP 8 +.B fill-style \fPstyle +Sets the fill style. Allowed parameters are "solid", "tiled", "stippled" and +"opaquestippled", which set the fill style to FillSolid, FillTiled, +FillStippled or FillOpaqueStippled, respectively. Example: +.EX +fill-style tiled +.EE +.TP 8 +.B font \fPfont-spec +Sets the font for text functions. Example: +.EX +font -*-*-*-R-*-*-*-120-*-*-*-*-ISO8859-1 +.EE +.TP 8 +.B fg \fPcolor-spec +.TQ +.B foreground \fPcolor-spec +Like \fIbackground\fP, but sets the current foreground color. Example: +.EX +foreground blue +.EE +.TP 8 +.B mask +This command is useful when you want to draw only in the region that really +needs to be repainted. Requires no arguments. +.TP 8 +.B function \fPfunction-spec +Sets the specific GC function. Allowed parameters are "set", "clear", "and", +"andreverse", "copy", "andinverted", "noop", "xor", "or", "nor", "equiv", +"invert", "orreverse", "copyinverted" and "nand", which set the function to +GXset, GXclear, GXand, GXandReverse, GXcopy, GXandInverted, GXnoop, GXxor, +GXor, GXnor, GXequiv, GXinvert, GXorReverse, GXcopyInverted or GXnand, +respectively. Example: +.EX +function xor +.EE +.TP 8 +.B join-style \fPstyle +Sets the join style. Allowed parameters are "miter", "round" and "bevel", +which set the join style to JoinMiter, JoinRound and JoinBevel, +respectively. Example: +.EX +join-style round +.EE +.TP 8 +.B image \fP{pixmap-spec},xs,ys,[xe,ye] +This function is implemented as a way to quickly compose complex +decorations in widgets. \fIPixmap-spec\fP is as defined in the +\fBPIXMAPS\fP section below. \fIxs\fP and \fIys\fP are the coordinates from +where to start copying the pixmap; \fIxe\fP and \fIye\fP are optional (they +default to xs + pixmap.width and ys + pixmap.height, respectively). If the +pixmap has a mask, the copy is masked accordingly. Example: +.EX +image pixmap.xpm,0,0,20,20 +.EE +.TP 8 +.B line \fPx1,y1,x2,y2 +.TQ +.B draw-line \fPx1,y1,x2,y2 +Draws a line with the current foreground color. Requires four arguments, +the starting and ending coordinate pairs. Example: +.EX +line +0,+0, -1,-1 +.EE +.TP 8 +.B line-width \fPinteger +Selects a line width for drawing. Example: +.EX +line-width 2 +.EE +.TP 8 +.B line-style \fPstyle +Sets the line style. Accepted parameters are "solid", "onoffdash" and +"doubledash", which set the line style to LineSolid, LineOnOffDash or +LineDoubleDash, respectively. Example: +.EX +line-style onoffdash +.EE +.TP 8 +.B lines \fPx1,y1,x2,y2 [...,xn,yn] +.TQ +.B draw-lines \fPx1,y1,x2,y2 [...,xn,yn] +Draws a list of lines. Any number of argument pairs may be supplied. +Example: +.EX +lines +0,-1, -1,-1, -1,+0 +.EE +.TP 8 +.B paint-string \fPx,y,"string" +Identical to draw-string, but also uses the background color. Example: +.EX + paint-string 10,20, "Sample text"\fP +.EE +.TP 8 +.B point \fPx,y +.TQ +.B draw-point \fPx,y +Draws a point. Requires two arguments, a coordinate pair. Example: +.EX +point +10,+10 +.EE +.TP 8 +.B plane-mask \fPinteger +Sets the plane mask. Requires an integer parameter. Example: +.EX +plane-mask -1 +.EE +.TP 8 +.B points \fPx1,y1 [...,xn,yn] +.TQ +.B draw-points \fPx1,y1 [...,xn,yn] +Draws a list of points at the specified coordinates. Example: +.EX +points +1,+2, +1,+4, +1,+6 +.EE +.TP 8 +.B segments \fPx1,y1,x2,y2 [...,xn,yn] +.TQ +.B draw-segments \fPx1,y1,x2,y2 [...,xn,yn] +Draws a list of segment lines. The number of parameters must be multiple +of 4. Example: +.EX +segments +1,+2,+1,-3, +2,-2,-3,-2 +.EE +.TP 8 +.B shape-mode \fPmode +Sets the shape mode used in \fIfill-polygon\fP. Accepted parameters are +"complex", "convex" or "nonconvex", which set the shape mode to Complex, +Convex or Nonconvex, accordingly. Example: +.EX +shape-mode convex +.EE +.TP 8 +.B stipple \fPpixmap-spec +Sets the pixmap for a stipple. Requires a pixmap parameter, as described +in the \fBPIXMAPS\fP section below. Example: +.EX +stipple plaid +.EE +.TP 8 +.B subwindow-mode \fPmode +Sets the subwindow mode in the GC. Accepted parameters are +"includeinferiors" and "clipbychildren", which set the subwindow mode to +IncludeInferiors or ClipByChildren, respectively. Example: +.EX +subwindow-mode includeinferiors +.EE +.TP 8 +.B tile \fPpixmap-spec +Sets the pixmap for a tile. Requires a pixmap parameter, as described +in the \fBPIXMAPS\fP section below. Example: +.EX +tile xlogo11?foreground=red&background=gray80 +.EE +.TP 8 +.B ts-origin \fPx,y +Sets the tile stipple x and y origin. Requires two arguments, a x and y +coordinate. Example: +.EX +ts-origin 10,10 +.EE +.TP 8 +.B umask +Disables the GC mask, if it has been set with the command \fImask\fP. +Requires no arguments. +.PP +Example for drawing a shadow effect in a widget: +.EX +foreground gray30;\e +draw-lines +1,-1,-1,-1,-1,+1;\e +foreground gray85;\e +draw-lines -1,+0,+0,+0,+0,-1 +.EE +.SH PIXMAPS +A String to Pixmap converter has been added to \fBXaw\fP. This converter +is meant to be extended, and has enough abstraction to allow loading +several image formats. It uses a format that resembles a \fIURL\fP, with +the syntax: +.PP +.I [type:]name[?arg=val[{&}...]] +.PP +\fBType\fP can be one of \fIbitmap\fP, \fIgradient\fP or \fIxpm\fP. +.PP +\fBName\fP may be a file name, or, in the case of type \fIgradient\fP, may be +either \fIvertical\fP or \fIhorizontal\fP. +.PP +\fBArg=val\fP is a list of arguments to the converter. An argument list is +preceded by a question mark, and multiple arguments are separated by +ampersands. The most common arguments are \fIforeground\fP and +\fIbackground\fP. Gradients also support the arguments \fIstart\fP and +\fIend\fP (colors with which to start and end the gradient); the +\fPsteps\fP argument, to allow using less colors; and the \fIdimension\fP +argument to specify the size of the gradient. The \fIxpm\fP converter +understands the \fIcloseness\fP argument, which aids in using fewer colors +(useful if you have a limited colormap). +.SH TEXT WIDGET +Most of the changes to this version of the Xaw library were done in the +TextWidget, TextSrcObject, TextSinkObject and related files. +.PP +A couple of highly visible changes in the Text widget are due to many bugs +in the Xaw6 implementation involving scrollbars and auto-resizing. +Scrollbars being added or removed caused several problems in keeping the +text cursor visible, and in Xaw6 it was very easy to have a widget thinking +the cursor was visible, when it was not. Also, permitting automatic +resizing of the widget to a larger geometry created other problems, making +it difficult to have a consistent layout in the application, and, if the +window manager did not interfere, windows larger than the screen could +result. Therefore, some functionality involving scrollbars and +auto-resizing has been disabled; see the section on new and modified +Text widget resources below. +.PP +The Text widget's default key bindings were originally based on the Emacs +text editor. In this release, even more operations familiar to Emacs users +have been added. New text actions include: +.TP 8 +.B indent +Indents text blocks. Not bound by default. The Text widget also does not +attempt to perform auto-indentation of its source object by default. +.TP 8 +.B keyboard-reset +Resets the keyboard state. Reverts the action multiplier to 1, and if undo +is enabled, toggles between undo and redo. Bound by default to +\fIControl<Key>G\fP. +.TP 8 +.B kill-ring-yank +In this version of Xaw, text killed in any text field is kept in memory, +allowing cut and paste operations internally to the program between text +fields. Bound by default to \fIMeta<Key>Y\fP. +.TP 8 +.B numeric +Listed here only for purposes of documentation. Called by default when one +of the characters \fI1, 2, 3, 4, 5, 6, 7, 8, 9, 0,\fP or \fI-\fP is typed, +allowing composition of the multiplication number of text actions. +.TP 8 +.B set-keyboard-focus +Sets the input focus of the top level widget to the text field. Not +enabled by default, but bound to the \fI<Btn1Down>\fP event. +.TP 8 +.B toggle-overwrite +Toggles overwrite mode. In overwrite mode, any text inserted in a text +field will replace existing text. Bound by default to \fI<Key>Insert\fP. +.TP 8 +.B undo +Sets the \fIenableUndo\fP resource of the textSrcObject. Not enabled by +default, but bound to \fIControl<Key>_\fP. +.PP +New and modified Text widget resources include: +.TP 8 +.B justify (\fPClass\fB Justify) +Sets the text justification. Can be one of \fIleft, right, center\fP, or +\fIfull\fP. Only enabled when the \fIautoFill\fP resource is set, and the +resources \fIleftColumn\fP and \fIrightColumn\fP are correctly set. +.TP 8 +.B leftColumn (\fPClass\fB Column) +Specifies the left column at which to break text. Text lines started with +an alphanumeric character will automatically start at this column. +.TP 8 +.B positionCallback (\fPClass\fB Callback) +Allows installation of a callback to be called every time the cursor is +moved, and/or the file changes its size. The callback is called with a +pointer to a structure containing the following data: +.nf +typedef struct { + int line_number; + int column_number; + XawTextPosition insert_position; + XawTextPosition last_position; + Boolean overwrite_mode; +} XawTextPositionInfo; +.fi +This callback is intended to help programmers write text editors based +on the Xaw widget set. +.TP 8 +.B resize (\fPClass\fB Resize) +No longer supported, but recognized for backward compatibility with +resource specifications written for the Xaw6 Text widget. +.TP 8 +.B rightColumn (\fPClass\fB Column) +Specifies the right column at which to break text. Text lines started with +an alphanumeric character will automatically end at this column. +.TP 8 +.B scrollHorizontal (\fPClass\fB Scroll) +.TQ +.B scrollVertical (\fPClass\fB Scroll) +These resources control the placement of scrollbars on the left and bottom +edges of the Text widget. They accept the values \fIXawtextScrollAlways\fP +and \fIXawtextScrollNever\fP. A converter is registered for this resource +that will convert the following strings: \fIalways\fP and \fInever\fP. The +value \fIXawtextScrollWhenNeeded\fP (and \fIwhenNeeded\fP, recognized by +the converter), is accepted for backwards compatibility with resource +specifications written for the Xaw6 Text widget, but ignored (effectively +treated as \fIXawtextScrollNever\fP). +.SH TEXT SOURCE OBJECT +The textSrcObject allows display of its contents to more than one window, +and also stores undo information. The new resources for the textSrcObject +are: +.TP 8 +.B callback (\fPClass\fB Callback) +Previous versions of Xaw had this resource in subclasses of the TextSource +object. This was changed to make it possible to tell the callback the +state of the text when undo is enabled. +.TP 8 +.B enableUndo (\fPClass\fB Undo) +A boolean resource that enables or disables the undo function. The default +value is False. +.TP 8 +.B sourceChanged (\fPClass\fB Changed) +Like the callback resource, this resource was previously in subclasses of +the TextSource object. It is now in the textSrcObject to control the +changed/unchanged state when undo is enabled. +.SH TEXT SINK OBJECT +The textSinkObject subclasses asciiSinkObject and multiSinkObject have been +changed slightly to use a new cursor shape (no longer a caret at the +baseline) that indicates the input focus of the text widget, and allow +specification of the cursor color. The new resource is: +.TP 8 +.B cursorColor (\fPClass\fB Color) +Sets the cursor color of the text. This color is also used to draw +selected text. +.SH SIMPLE MENU WIDGET +The simpleMenuWidget algorithm to lay out menu entries has been changed to +enable multiple columns when a single column does not fit on the screen. +It was also modified to enable submenus. +.SH SME BSB OBJECT +A new resource has been added to the smeBSBObject to allow binding submenus +to it. The new resource is: +.TP 8 +.B menuName (\fPClass\fB MenuName) +Specifies the name of the popup widget to be popped up when the pointer is +over the menu entry, or NULL. Note that the named menu must be a child of +the popup parent of the smeBSBObject. +.SH AUTHORS +The original X Consortium version of the Athena Widget Set and its +documentation were the work of many people, including Chris D. Peterson, +Ralph Swick, Mark Ackerman, Donna Converse, Jim Fulton, Loretta +Guarino-Reid, Charles Haynes, Rich Hyde, Mary Larson, Joel McCormack, Ron +Newman, Jeanne Rich, Terry Weissman, Mike Gancarz, Phil Karlton, Kathleen +Langone, Ram Rao, Smokey Wallace, Al Mento, and Jean Diaz. +.PP +The additions and modifications to \fIXaw\fR which were +originally made for XFree86 were written by Paulo +C\('esar Pereira de Andrade. +.SH SEE ALSO +.I Athena Widget Set - C Language Interface diff --git a/old-doc/CHANGES b/old-doc/CHANGES new file mode 100644 index 0000000..a6a95fd --- /dev/null +++ b/old-doc/CHANGES @@ -0,0 +1,153 @@ + + These changes have been made to Xaw since X11R4. + + + +Documentation: + Fixed definition of XtAppInitialize(). + + Changed all references to XawOrient* and XtOrient* to Xtorient*. + + Many other corrections and clarifications. + +Everywhere: + Function prototypes for public interfaces. + + Many bugs not mentioned here have been fixed. + +AllWidgets: + Add WidgetNode table for use with listres and viewres. + +AsciiSrc (Text): + No warning message is printed when the file can not be + written to, the return value should be enough info. + + GetValues on the string resource was failing when + "useStringInPlace" was set to true. + + Memory leak when freeing pieces in a source of type "ascii String" + has been plugged. + + Buffer is now updated whenever the "string" resource is set using + XtSetValues(). If type is file then the file is read in again. + +Box: + The public header file now includes Xmu/Converters.h for the + orientation resources. + +Clock: + Made subclass of simple instead of Core + +Command: + Fixed bug in changing shape style to Rectangular. + +Dialog: + Resource Type of Icon changed from Pixmap -> Bitmap. + +Form: + The geometry handler now will now disallow geometry management + reqests that will force the child outside the Form's window. + + Fixed missing parens typo in PreferredGeometry. + + Fixed EdgeTypes to be Xaw* instead of Xt*, but left the + old definitions around with #define so that code will still work. + + StringToWidget converter no longer caches resources. + +Logo: + Made subclass of simple instead of Core. + Fixed reverse video. + +Mailbox: + Made subclass of simple instead of Core. + Fixed reverse video and many other bugs. + +MenuButton: +* The MenuButton widget no longer places a server grab on itself. + Instead, PopupMenu is registered as a grab action. As a result + of this, clients which popped up menus without using XtMenuPopup + or MenuPopup or PopupMenu in the menu button translations will + fail to have a grab active. They should make a call to + XtRegisterGrabAction on the appropriate action in the application + initialization routine, or use a different translation. + +Paned: + The public header file now includes Xmu/Converters.h for the + orientation resources. + +Panner: This widget is new in R5. + +Porthole: + New for R5. + +Scrollbar: + Fixed bug that could call XtReleaseGC() with garbage + Made subclass of simple instead of Core + + Type of thumb resource is XtRBitmap; it used to be XtRPixmap. + However, if applications provide the resource conversion, the + Scrollbar's SetValues can still handle pixmaps of correct depth. + +Simple: + Added a color cursor converter. and the new resource types: + XtNpointerColor + XtNpointerColorBackground + XtNcursorName + +SmeBSB: + Right bitmaps are now painted in the correct location. + + Right and Left Bitmaps can be specified in resource files, and + at startup time. + +Text: + If there is no current selection the the selection extends + from the insert point, rather than some random location. + + Forward (Backward) Paragraph works at the paragraph boundaries now. + + Selecting a word now transitions correctly at BOTH end points. + + Infinite loop when using fill paragraph in a read only text widget + has been found and fixed. + + When the "resize" resource is set the text will start up with + exactly enough space to contain the text in the widget. + + Fixed a bug that could cause an infinite loop when Meta-Q was used + to invoke the form-paragraph function on a read-only text widget. + + Exposures fixed. + +TextP.h: + Symbolic constants private to the Text widget should not conflict + with operating system headers files. The names of these symbolic + constants have each had the prefix Xaw added to them: + #define XawLF 0x0a + #define XawCR 0x0d + #define XawTAB 0x09 + #define XawBS 0x08 + #define XawSP 0x20 + #define XawDEL 0x7f + #define XawBSLASH '\\' + + +Toggle: +* Toggle widget state is preserved across changes in sensitivity. + + A string to widget converter is regisetered for radio groups. + +Tree: + New for R5. + +Paned: + Fixed bug that caused XtGeometryYes returns to have bogus values, + causes panes to get random sizes. + +Vendor: + Added support for the Resource Editor. + Fixed bug causing Shell to ignore all but first child. + +Viewport: + Added XawPannerReport support. diff --git a/old-doc/Changelog b/old-doc/Changelog new file mode 100644 index 0000000..cabbb2c --- /dev/null +++ b/old-doc/Changelog @@ -0,0 +1,1370 @@ +Patch 1 (#1655) 15 April 1998 + + Description of the actions system: +-------------------------------------------------------------------- + All the actions have the syntax: + +action-name(boolean-expression, args) + + Where: +action-name: + Any string with a translation binding in the binary for the widget. + +boolean-expression: + [{~}]variable-name|resource-name|constant-name[{&|^}[[{~}]variable-name|resource-name|constant-name]]... + +variable-name: + Any string starting with a '$' character (actually it's not possible + to mask this character; I'll fix it). Variables are actually created + with the translations 'declare' and 'get-values'. Example: + get-values(1, $x, x) + declare(1, $armed, true) + +resource-name: + Any resource name of the widget. Note that it requires a <TYPE> to + string converter in the code (I added some on the patches), since + all variables values are stored in a 'String' format. Example: + borderWidth + height + font + background + +constant-name: + Especial values. They aren't normally contants, but a special state + not triggered with resources or variables (They have the highest + precedence, so, to allow these strings as resource names I'll need + to allow some sort of escape sequences). Examples: + mine # event->xany.window == XtWindow(widget) + faked # event->xany.send_event != 0 + true # you know + false # " " + +args: + Special strings values interpreted by the translation binding. + +The operators (currently) understood are: + ~ - NOT + & - AND + | - OR + ^ - XOR + ( - RP + ) - LP + The final result value is and'ed with 1. + +Sample translation to make a label widget behave like a button: +<Map>:\ + get-values(1, $fg, foreground, $bg, background)\n\ +<Btn1Down>:\ + set-values(1, foreground, yellow, background, gray30)\n\ +<Btn1Up>:\ + set-values(1, foreground, $fg, background, $bg)\n + + + Description of the displayList system: +-------------------------------------------------------------------- + The display list has the syntax: + +[class-name:]function-name args[{;|\n}]... + + Where: +class-name: + Any registered set of functions. The code registers the class 'xlib', + and if the class name is not specified, this class is assumed. + +function-name: + A string binding to the correct function to be called. + +args: + A set of converted and shareable arguments, to the function. The + positioning/sizing arguments currently implemented have the syntax: +{+-}<integer> or <integer>/<integer>. Examples: + +0,+0 top, left + -0,-0 bottom, right + -+10,-+10 bottom+10, right+10 + +0,1/2 left, vcenter + + All displayLists are shared by: + widget->core.screen + widget->core.colormap + widget->core.depth + I have added only partial code for handling non-windowed widgets (gadgets). +I'll fix it. + + Example for drawing two lines crossing the widget: +foreground black;\ +line +0,+0,-0,-0;\ +line +0,-0,-0,+0 + + + +Patch 2 (#1660) 19 April 1998 + + + More functions for displayList's + + Fixes for simpleMenuWidget, xfontsel should work very better now. Try + this with the newer patches to verify the changes: + xfontsel -xrm '*XFontSel*SimpleMenu*font: +-*-helvetica-medium-r-*-*-16-*-*-*-*-*-*-1' + + Small bug fix to boxWidget, viewres should work better now. Try this + to verify the changes: + viewres -xrm '*Viewres*Box.borderWidth: 1' + + Small bug fix to panedWidget, when pressing in a gripWidget but not + moving the pointer, or releasing at the same coordinates. + +Patch 3 (#1673) 25 April 1998 + + + Changes in layout code for the Form widget. To see the changes, run xcalc + and resize it several times (try giving it a very small size and the + restore the size). The new code uses a 'known' reference size/position + to avoid integer rounding problems. + + A optimization for the Form widget. Now it unmaps itself before resizing + the child widgets. This way the layout process is very faster. + + The List widget will try to fit in a 32767x32767 window size. It checks + if the width or height will become bigger than 32767 and if will, changes + the number of columns. This fixes xman (at least for me, that have several + entries in the section 3 of the manpages). + + New functions to displayList's and fixes to some bad bugs (I'm yet working + on that file). + + Change in the Scrollbar functionality. It was redrawing the thumb when + triggering the MoveThumb action. This is bad because several programs + choose to recalculate the thumb position with XawScrollbarSetThumb, causing + screen flickering. Now it redraws the thumb when triggering the NotifyThumb + action. To verify the changes, run xfm or xman and try to scroll past the + end of a window; it will keep erasing and redrawing the thumb. + + Other change in the Scrollbar is that it will only draw in the rectangle: + 1, 1, core.width - 1, core.height - 1. It is better when creatting a 3d + effect with displayList's. + + +Patch 4 (#1678) 3 May 1998 + +Included the patches for the recent problems with libXaw. +Several 'gratuitous' small changes, to compile cleanly with gcc -Wall. +Some bug fixes for DisplayList.c. +Colored pixmaps support. I'm building a abstraction layer for the colored + pixmaps, so that it should be easy to support more pixmap formats + (actually, only X bitmaps). + + +Patch 5 (#1686) 11 May 1998 + + + Patch to libXmu, so that the StringToCursor converter will understand the + string 'None', that means not to use a cursor. This is useful when + overriding resource settings, and the user wants to use the parent window + cursor, or the root window cursor. Any unrecognized name will generate + a 'None' cursor, but then with a warning message. + + SimpleWidget was modified to allow setting the cursor to none, when it + was a valid cursor. + + Modification in the Actions.c, + from: + typedef struct _XawActionVar { + XrmQuark qname; + String value; + } XawActionVar; + to: + typedef struct _XawActionVar { + XrmQuark qname; + XrmQuark qvalue; + } XawActionVar; + This does not cause any problems, since the exported interface remains + the same. This is required to avoid to much copies of the same string. + + Values of action variables can start with '$'. + + If a resource name clashes with a special constant name when evaluating + a boolean expression (in the translations code), it's enough + start the resource name with '\\' (it can always be used, but is + only useful if there is a name clash :). + + The only code that loads data files actually is the pixmap code. To avoid + security problems, the code only loads files that are group readable, + regular file, non suid and non sgid. + + If the code to load a pixmap does not find a match, and the pixmap name + has a extension, try without the extension. + + Function 'line-with' added to displayList code. + + Added DisplayListToString and PixmapToString converters. + + Bug fixes in the pixmap name interpretation. + + +Patch 6 (#1701) 24 May 1998 + + Xaw + ------ + + Allows setting the resources label_x and label_y inherited from labelWidget. + This is useful for moving the contents of a button when it is pressed + ( I included a simple test for it ) + + Added OS/2 patchs + + The buffer overflow problems were resolved in a different way. I added + a function XmuSnprintf, that is used by Xaw and Xmu. + + Correction of a problem in SimpleMenu, when it tries to optimize the + space used by the menu. + + Xmu + ----- + + Function XmuNCopyISOLatin1Lowered, defined in <X11/Xmu/CharSet.h> + + Function XmuSnprintf, defined in <X11/Xmu/SysUtil.h> + + All ocurrences of sprintf were replaced by XmuSnprintf and all ocurrences + of XmuCopyISOLatin1Lowered were replaced by XmuNCopyISOLation1Lowered. + + +Patch 7 (#1738) 21 June 1998 + + + Corrected problem with the Command widget, when it was made insensitive + without calling the 'reset' action. + + Rework of the SimpleMenu code for optimizing the space used. Now it + really works as intended. + + Fixed portability problems with my previous patches. + + Corrected problem pointed by 'grano@cs.Helsinki.FI'. He have followed up + a bug report to the devel mailing list. While the problem exist, his + patch was not complete, so I did a rework of the AsciiSrc.c:Scan() and + MultiSrc.c:Scan() functions. + + I added clipping code to the {Ascii,Multi}Sink widgets, to allow use of + displayList's as decoration. The best solution I found to avoid too much + server requests, and keep full binary compatability was to use the resize + method of these widgets, to tell them to the parent widget have changed + it's size. + + Now the TextWidget has a xterm/emacs like cursor. And it is possible to + especify a cursor color. + + Fixed several problems caused by code assuming a line of text will be + shown as one line in the TextWidget. This is not always true when + it uses XawtextWrapLine or XawTextWrapWord, the most common problem was + the cursor becomming invisible, after calling the function + Text.c:_XawTextShowPosition() that is called to make sure it is visible ;) + + Added code that it will not forget the cursor distance from the left of + the window while moving the cursor one line up or down. + + Ansification of the text code (not yet complete). Private routines now + uses prototypes and wide parameters. External routines were kept + as before (but with prototypes not masked by NeedFunctionPrototypes), + to avoid binary compatability problems. The bigger problem I found in the + ansification was a function with 6 parameters being called with only 5. + + Several routines were rewritten, sometimes from scratch. + + The cursor navigation of the TextWidget was completely reviewed. It + should be very familiar to Emacs users. The most Emacs like behaviour is + when the cursor in move one line up or down and becomes invisible; the + text will be scrolled so that the line with the cursor will be centered + in the screen. Also, when doing page up, the cursor will be positioned + in the bottom-left, instead of allways in the top-left. + +Patch 8 (#1752) 27 June 1998 + + + There was a problem with the previous patch regarding to portability. + The problem was strcasecmp. I was planning to provide the funcionality + in libXmu, and forgot when creating the previous patch :(. There is + already a strcasecmp equivalent in libXmu, that is + Lower.c:XmuCompareISOLatin1(), so I used that function. + + The previous patch was working correctly for viewing text, but there were + some cases the text window could end not displaying correctly the text. + This problem was fixed. + + Now, the only real need of scrollbars is when doing long jumps on the + text, because the cursor will be always visible since this new patch + does horizontal scrolling automatically. + + +Patch 9 (#1755) 28 June 1998 + + + Removed all my RCS idents in the files. + + Declared functions as static in the prototype and in the definition + (this basically reverts a previous patch, but should help when applying + the patches sequentially). + + Changed the code in Pixmap.c to use strtok instead of strsep, that is + not portable. + + Corrected problem with previous patch that would cause trouble when + a text widget had more than 32K bytes, and would also cause offset + mismatches if a program access private structures (AsciiSinkP.h). + + +#1776 6 July 1998 + +Corrected problem when moving the cursor over a non-printing character, + i.e. ^Q ^X +Does not allow anymore scrolling of the text width Ctrl+Z if the text has + only one line, or only one line of text. +Several changes in the TextWidget. I did not gratuitously break binary + compatability. Source compatability is only granted to programs that + do not access private structures. This is required because there are + several changes in the behaviour of the TextWidget, and if a program + becomes non compilable, it is because it will not work properly with + the changes in the text widget (please read bellow for a explanation) +Better cursor navigation when moving line-up or line-down over a tab: + cursor + | + v + spaces | |#| | | |text + tab | |text + Move one line down: + before: + tab |# |text + now: + tab | |#ext +There were several problems in the Text.c:_XawTextReplace(), when deleting + a character and the cursor (shoud be) moved to the previous line. This + problem was corrected. +The text code was doing too much redrawing! When typping text, it would + redraw all the current line at each character typped, and also redraw the + entire window till the bottom. Now it only redraws the minimum necessary + (and makes a minimum of requests for the Xserver, when clearing areas), + most of these problems were related to Text.c:_XawTextReplace() (rewritten + from scratch), Text.c:_BuildLineTable() (mostly rewritten) and + Text.c:DisplayText() (mostly rewritten). +Now, when selecting text, with: button1-down, button1-move, the window will + be scrolled automatically, if the mouse is moved to the top or bottom of + the text window, making it easier to extend selections. +Added a set-keyboard-focus translation to the text code, and in the + default translation, it is called when pressing the left mouse button over + a text widget (so that the mouse does not need to be over the text window + when typping) + +These are the changes to Xaw that made it not fully source compatable (I'm +open to comments, to make it source compatable, but as I said above, if +a program does not compile anymore, it is because it is not granted it will +work properly): +scrollMode set to WhenNeeded is not supported anymore. I spent several + hours fighting side-effects caused when a scrollbar is created or destroyed + 'on demand', and have (after tired of long debug sessions) choosed that + it is not required (it saves a lot of potencial unespected conditions + being found by a user). I changed the 'type' of the scroll mode to Boolean, + so, to have a scrollbar, is enough to say: *Text.scrollVertical: True. + Since the type now is Boolean, Xt will print warning messages when the + scroll is set to 'Always', 'Never' or 'WhenNeeded' +automatic resize is nonsense since the text does automatic horizontal + scrolling. IMHO, to be useful, automatic resize should also shrink the + text window when needed, anyway, it's not required anymore + +Comments: +auto-fill mode does not work properly (never did) +wrap-mode set to line may not work properly +wrap-mode set to word does not work properly always (never did) +the multiply should be setable to a variable value; the default value + is 4, i.e. Ctrl+U <text+action> +I will work on the itens listed above, and I'm also planning: +one level undo, for text actions +C style indentation and 'jumping' the cursor to show matching '(', '[' + and '{' +other things that I don't remember now :) + + +-- XMU -- +Moved the code clipping code I have put in Text.c in my previous patch to + Xmu/Clip.c. There was a bug in the code I have put in Text.c (this is what + I get by cutting and pasting code under a #if 0 :(), but it was corrected. + The code in the new file 'Clip.c' is very useful for creating clipiing lists + and thus, avoiding too much server requests, or code for the same + functionality (poorly) repeteated in several places around the libary. This + code is now heavily used by the TextWidget. + + +-- XEDIT -- +Removed a XDefineCursor in xedit.c:main(). There are several ways to specify + a cursor for a program (most times inherited from the wm decoration window), + so, it is better to let the user choose one. +Before starting the main loop, now xedit sets the keyboard focus to the + text window if a file was loaded, or to the prompt for a file name if + none was especified in the command line (do not use the new xedit without + the new Xaw library, or you will not be able to change the keyboard focus). +Updated the Scrollbar configurations in Xedit.ad + + +#1788 12 July 1998 + +-- TextWidget -- + + Corrected problem whem moving the cursor over a non-printing character + + Now, does not allow scroll with ^Z when there is only one line of text + + Automatic resize was removed, it is not required with automatic horizontal + scroll, but I will look for programs that rely on it; the only program + affected (that I know) is xmh, because it popups dialogs of a small size, + and expects that the text widget (with a warning message) do a geometry + request. + + Scroll mode set to "WhenNeeded" was removed. It generates several unespected + conditions when editing text, and the new feature of automatic scrolling + the text widget while typping is more useful. + + Removed a leak in TextAction.c:AutoFill(), generated by the code + text.ptr = (char *)XtMalloc(sizeof(wchar_t) * 2); + that memory was never released, but the fix was simple, since the amount + of memory requested is fixed. + + Several optimizations in the redisplay of the text. + + Now, wrap mode set to word or line is expected to work, while typping text. + + AutoFill will only break lines in word boundaries now. + + Added a set-keyboard-focus action to TextAction.c, so that when pressing + the left button over a text widget, it will receive the keyboard focus. + This behaviour is the default, but can be disabled, with something like: + *Text.translations: #override\n<Btn1Down>: select-start()\n + in your .Xdefaults. + + Corrected several cases that would left the text widget showing incorrect + data. All the problems should have been fixed, but in case you find one, + a quick fix is: + *Text.backgroundPixmap: black?foreground=<some-color> + because it does not try to optimize the redrawing when using a background + pixmap, and thus, avoid several possible problems. + + +-- XAW -- + + I had added a XawStackAlloc definition to "Private.h", to avoid a XtMalloc + request for every character typped in TextAction.c:InsertChar(), but + when syncing with 3.9Aj, saw that the file "XawAlloc.h" is no longer + required. Please, remove XawAlloc.h from 3.9Aj. + + +-- XMU -- + + Added the file Clip.c, with clipping code, that, now is being used by + the text widget, but can be used by other widgets. + +-- xedit -- + + Removed a XDefineCursor from xedit.c:main() + + I have added a XtSetKeyboardFocus in xedit.c:main(), but comented it + because it would make xedit unusable with previous versions of Xaw, + or with the Xaw replacements (Xaw3d, Xaw95 ...) + +Comments: + I wrote a lot of code to work properly with italic fonts in the text widget, +that code made the cursor do not erase portions of the text while moving the +it, but it was failing at some places that would need that the TextWidget, +and not only the {Ascii,Multi}SinkObject had access to the fonts, so I +choosed to left it to the future (and keep the sources simple, by now). +The text widget is useable with italic fonts, but fonts with: + f->per_char[<char> - f->min_char_or_byte2].rbearing + > f->per_char[<char> - f->min_char_or_byte2].width +or + f->per_char[<char> - f->min_char_or_byte2].lbearing < 0 +will not allways be displayed correctly. + + I haved also added a xedit configuration file to this mail. + + +#1842 27 July 1998 + +Fixed problem with the default macro for type conversion, where it was + possible to the code tell the wrong size of a string, since it was + returning the string size with 'strlen' but making the copy with strcpy. +Complete ansification of Xaw (and Xmu). +Corrected some problems caused due to an alteration in the text code, to + make the cursor always visible when the wrap mode is 'line' or 'word'. +Text.c:VJump() was made a bit smarter and a problem that would cause it + to jump incorrectly was also corrected so that now the jumping should be + very smooth. +Corrected problem that would cause a coredump due to the + Text.c:_XawTextReplace() deferencing a NULL pointer. Now ctx->text.lt.info + is initialized when the text widget is created, solving this problem. +All the variables with name 'new' and 'class' where renamed to 'cnew' and + 'cclass'. This allows even building Xaw with 'gcc -x c++'. +Variables shadowing other variables or functions where also renamed. +Static functions were changed to use wide parameters, where applicable. +(Almost) every time a StringTo<Type> converter is installed in the class + initialization of a widget, the code also installs a <Type>ToString converter + since now editres seens to work better. +Complete reestilization of the indentation. See the files Template*.{c,h}. +Corrected problem with the 'virtual' function Layout of the Form widget. That + function requires 4 parameters, but the Viewport widget (a Form subclass) was + calling that function with only 3 parameters; the ansification flagred that + error. +TextTr.c was modified to have only one string. I believe that that weird + thing was due to the inheritance of compatability with some very old and + probably buggy ld. +Xaw is expected to be binary compatable with R6.3; there are some + preprocessor macros that keeps binary compatability, and unless the gains + of breaking binary compatability show worth enough (and people think) it + is good that code would be made default, otherwise it will be forgotten. +I have also added a XFree86 copyright notice to Text.c, since there is + a very large amount of work in that file (and it is not yet ready). +--------------------- + +-------- Xmu -------- +Complete ansification of Xmu. +Rework of EditresCom.c to allow editres working correctly. It was also + added a new feature, that allows editres finding some extra child widgets, + i.e. widgets that aren't a child of a subclass of composite and aren't in + the popup list. This modification is not enough, since it does not find + child widgets that don't a XtRWidget resource in the parent widget. +Rework of ShapeWidg.c, so that it will give the correct feeling to the + ellipse shape, and inversion of the oval, if shape is oval and + height > width. To see these changes, run a program with: + <prog> -xrm '*shapeStyle: ellipse' + and/or + <prog> -xrm '*shapeStyle: oval' +Revision of DrRndRect.c to make the widget looks 'more correct' when using: + <prog> -xrm '*shapeStyle: roundedRectangle' +--------------------- + +------ editres ------ +Added small patch to bug in handler.c so that editres will correctly now. +--------------------- + +------- xedit ------- +Changed the resources file, to avoid a problem when resizing xedit to a + very small size and than restoring it's size. Probably the culprit is the + Paned widget, but the new resource file is at least a good workaround for + the problem. +The resource file was also modified so that the default xedit size will + give a 80x25 rows/columns when using the default font. +--------------------- + +-------- xgc -------- +Small patch to clear correctly the status text window, when pressing the + 'Clear window' button. Note that this patch showed a bug in + Xaw/{Ascii,Multi}Src.c; only apply this patch with the latest Xaw, or + be sure that Xaw/{Ascii,Multi}Src.c:*SetValues() has something like: + if (old_src->ascii_src.ascii_length != src->ascii_src.ascii_length) + src->ascii_src.piece_size = src->ascii_src.ascii_length + 1; + instead of: + if (old_src->ascii_src.ascii_length != src->ascii_src.ascii_length) + src->ascii_src.piece_size = src->ascii_src.ascii_length; + or it will enter a infinite XtMalloc(0) loop :( +also fixed a possible buffer overflow while searching the source of the + bug described above. +--------------------- + +#1945, 31 Aug 1998 + +-- XAW -- + + Corrected bug in Viewport.c:ComputeLayout(), that would put the scrollbar + in the incorrect position, if w->viewport.useright == True + + Corrected bug in Converters.c:_XawCvtCARD32ToString(), so that now it + will correctly format the converted value. + + Corrected problem in {Ascii,Multi}Src.c:Search(), that would cause a + incorrect offset to be returned, if the searched text (or a substring of + it) were in a 'Piece' boundary. + + Some small patches to other sections of the code, to reduce the number + of warnings generated by gcc, when using more restrictive warning options. + +-- XMU -- + + Corrected a problem in Atoms.c:GetAtomName(), to return a NULL pointer, + instead of a const if the given atom is 0. + + Corrected a typo in Xmu.h + + Several 'ansification' patches, to get function definitions and avoid + unecessary definitions. + + +#2028, 2033, 7 Oct 1998 + +-- Xaw -- +Added a delete translation to the text widget, that deletes the current + selection if any, else the backwards char. +Corrected bug that would not update correctly the screen if page-up or + page-down was pressed while there was an selection. +Added a ^Q<any-char> translation to the text widget, to be able to insert + any char in the text. +Changed TextAction.c:Move() to set ctx->text.showposition, so that even + if the cursor did not change the position, it will become visible. +Corrected problem with the 'form-paragraph' translation, so that the + text will be always correclty shown. +Modified the automatic scrolling of the text to one line at a time, to + make it easier to see what is being selected. +Added a 'hack' to be able to type ^U<any-numeric-sequence> to be able + set the multiply of the text widget. Since it is a hack (besides seens + to work very well) it can be disabled with -DNO_NUMERIC_HACK +Corrected a nasty bug in Text.c:CvtStringToScrollMode(); XtConvertAndStore + can't be called from a type converter! +added UNDO/REDO to the text widget. Please try it, I think it is very nice. + Undo is enabled by the new resource 'enableUndo', and, by default is + triggered with 'Ctrl+_'. + +-- editres -- +Resubmitting a patch to editres/handler.c, to make editres work properly. + +-- xedit -- +NOTE that with this patch, xedit probably will not work with Xaw3d, neXtaw... + this surelly can be fixed, or in the xedit side or the *Xaw* side, but + the patch seens to be necessary. +Changed the defaults file to be more user friendly and previsible. + Added some 'Emacs like' binding translations. +Added file completion in the filename prompt. This is a very nice + feature, but I'm not sure if the code is portable to all the XFree86 + supported platforms (surely it will not work 'as is' with OS/2). + + +#2083 18 Oct 1998 + +-- XAW -- +Changed the functions {Ascii,Multi}Sink.c:CharWidth and PaintText, to + improve speed, and avoid too much recalculations. On normal files, it + becames about 5:1 faster, but can go up to 20:1 when editting files with + very large lines. Besides this speed improvement, I believe it can + surely be made faster (based on comparition with some popular X editors). +Changed the way the AsciiSink prints characters with value bigger than + 126 decimal. Now it prints DEL as ^?, and the other characters as \XXX + where 'X' is an octal digit. The MultiSink widget was unchanged in this + respect, i.e. when calling xedit with something like: + xedit -xrm '*international: true' +Converted all calls to strncpy, in AsciiSrc.c to memcpy, so that the (ascii) + text widget will work properly with data containing nulls. +Added a experimental 'Xaw Scan Type' XawstAlphaNumeric, that shoud make + edition of C (or any other language) easier in xedit (i.e. the text widget). + It can be tested with Ctrl-Left and Ctrl-Right, by now. +Changed the TextWidget to handle text lines that would result in more than + 32767 pixels. Besides the text widget is not meant to be used in the + edition of binary files, this change allows it. +Changed Text.c:TextScroll() to be smarter when calculating the offset of + the line table on scroll up. +Added a nice feature, to show the matching '(', '[' or '{', when a ')', + ']' or '}' is typped. +Changed TextAction.c:FormParagraph() to generate only one undo/redo step. + +-- xedit -- +Changed the defaults file to enable backups and made the backup suffix + the character '~'. +Replaced all instances of sprintf by XmuSnprintf. +Changed xedit to set the label when saving a file also, to reflect what + is being edited correctly. +Corrected a bug in the new action 'file-completion', to replace correctly + the home directory, and keep correctly whatever was after the '~'. This + isn't the correct place to this code (xedit/commands.c), since there are + several other file name prompt windows in Xaw, but since it is required + another window to show the possible matches, I'll study a better way to + implement it. +Added a 'hints' feature to xedit. Instead of a 'dead' + "Use Control-S and Control-R to Search." label, now it allows the label + string being changed at user settable intervals. + + +#2205 10 Nov 1998 + +-- xaw -- + + Fixed some 16 bit overflows in AsciiSink.c and some cases where it would draw + past the end of the text window (a no-op), the overflows were not a + problem, but could left the text window with incorrect data. + + Moved the undo/redo code to TextSrc.c, and some code/data from + {Ascii,Multi}Src.c to TextSrc.c. The callback now is called when the + source is changed, or becames unchanged due to an undo/redo. Also + changed the Scan procedure to be a bit faster. + + The asciiTextWidget will now accept a source or sink object being set at + creation time. + + Fixed the 'struct XawDisplayList' being redefined when compiling Xaw under + SunOS. + + Several changes to the SimpleMenuWidget to make the geometry management + work correctly when adding/removing/changing menu entries at run-time. + + Added a 'kill-ring' feature to the TextWidget. The behaviour is identical + to Emacs. Pressing C-K repeteadely will merge the lines being killed, so + that a C-Y latter will paste all the killed lines. + + Added the enough glue code (and as backwards compatible as possible) to + allow the *src object be shared between several TextWidgets. My initial idea + was to make the TextWidget be able to have more than one source, but, to + be backwards compatible, I did the reverse (the source can have more than + one TextWidget). + + Fixed a automatic wrap bug (TextWidget) that could eat non white space + characters (my previous patch to this problem was completely wrong). + +-- xedit -- + + Added a split-window feature to xedit. To keep xedit simple, it only allows + two windows at the same time: or subdivides in the vertical or horizontal. + + Added more some key-bindings, that should do the same as Emacs. + +#2291 5 Dec 1998 + +-- Xaw (only changes to the 'text' code) -- + + Changed the default 'piece size' from BUFSIZ to the value returned by + the getpagesize() function (or keep BUFSIZ if that value is smaller). + + Added a case sensitive option to the search popup. This is a 'hack' by + now, but should not cause trouble to anybody. + + Fixed a bug inserted when changing the code for the search, the only side + effect I saw was that the jumping cursor to show the matching '(', '[' or '{' + stopped working in my last patch. + + Moved back my change to the function XawTextSetSource. The 'correct' function + is _XawTextSetSource. This is only to make sure old code should compile + cleanly. + + Added line and column number calculation code (and a callback to tell when + that information changed) to the TextWidget. This was not an easy task, + because I tried to optimize as much as possible the code, and do relative + calculations, instead of scanning the entire file to count the number of + lines (there are several special cases, when removing/inserting text). + + Added the selection type XawselectAlphaNumeric. This adds one step in + the sequence word-line-all when doing multiclick in the text. + + Fixed some bugs in the 'kill ring' feature added in the last patch. Now + it is expected to never fail. + + Corrected the indentation of TextP.h, and changed more some fields. The + internal data of the TextWidget changed a lot, so it is not expected that + program code read directly the private data, at the price of requiring the + correct library version. + + Fixed a small bug in the undo code, that would 'think' the file was unchanged + in the incorrect position in the undo buffer. + + Changed the default key bindings for delete/kill word functions to use the + alpha numeric versions (this is better for coding, and more compatible with + other text editors). + +-- xedit -- + + Changed the labelWindow, to show the current line number (but it is also + possible to show the current column number, offset or file size). + + Fixed bug when saving the *scratch* buffer with a new name. + + The 'changedBitmap' is now correctly displayed on all the windows showing a + changed file. + + Small changes to the xedit man page. + + + +#2371 8 Jan 1999 + +--- Xaw --- + + More some changes to AsciiSrc.c:Scan(). This improves a bit the speed when + scanning text. + + Added sanity checking for AsciiSrc.c:Search(), to avoid the risk of + deferecing a null pointer (or reading memory out of the text piece) if the + searched text happens to be larger than a "piece size". + + Fixed bug when trying to optimize line number calculation, due to a typo, + while meaning XawTextWrapNever I wrote XawTextWrapLine. + + Fixed a problem shown by xclipboard, when setting the "string" resource + of the text source, the sink object was keeping the insertPosition in the + old text contents, and then, when showing the cursor, it was incorrectly + 'erasing' the old cursor position. + + Fixed problem in XawTextReplace, that would not update correctly all the + TextWidget's sharing the same source. + + Added a kill ring list to the text code. This works like the emacs feature, + but, unlike emacs, it is not required to press C-Y before M-Y, to start + looping through the kill ring list. To use it, just press M-Y repeteadly, + and all the text that was killed will be inserted, one at a time, so that + you can choose one. Note that the text inserted from the kill ring list + will also enter in the undo list. + + Changed the Move{Backward,Forward}Paragraph actions to make the cursor always + stop in a blank line. This makes only one step moving from a paragragh to + another, instead of two. + + Added code to check for overflows in the C-U<number> sequence. + + Changed the FormParagraph action to keep the cursor at the correct position. + + Changed the default translations in TextTr.c to get a more emacs like + behaviour with the kill ring list. + +--- xedit --- + + Added a few more resource settings to the Xedit-sample file. + + Added some sanity checkings when trying to save a file. This avoids the + case of saving a file with the name of a directory (but moving the directoy + to other name before). A possible case is: have a directory named 'dir', + saves a file as 'dir', but before saving, renames the directory as 'dir~'. + + Allows saving a file that xedit thinks is not changed (the file may have + changed on the disk, but the user really wants to rewrite it). + + Corrected several bugs in the FileCompletion action, and added a new + feature, that is to complete the partial names, when there is a '/' or '.' + after the cursor position. + + +#2479 19 Feb 1999 + +-- Xaw -- + + Fixed bug in the line numbering code, when removing lines before the + top position. + + Changed code to form regions to always show the cursor after formatting the + text. + +-- xedit -- + + Added code to keep the file mode, after saving. This is useful when editting + scripts, so that the executable flag will not be lost after edition. + + +#2544 12 Mar 1999 + +-- Xaw -- + Mostly changes to add support to latin-* languages in the text code, when not + using the international resource. +Actions.c: + + Corrected some bugs in the boolean expression parser. The old version would + not parse correclty parenthized expressions, and was giving equal precedence + to AND, OR and XOR (what is incorrect). +AsciiSink.c: + + Changed to display characters in the range 0x32-0x7e and 0xa0-0xff literally. + The other characters are represented as control-codes, as before. This is + better for edition of Latin-* text files. +AsciiText.c: + + Changed the code, so that even if the *international resource is not set, + _XawImRegister and _XawImUnregister are called for the text widget. This is + useful for latin-* locales, that use one byte wide characters, and makes Xaw + more compatable with modern toolkits, like qt and gtk. +List.c: + + Added code to work correctly with a background pixmap. + + Added a smarter code for list window size calculation, that is used if the + number of columns is especified to be zero (automatic). +MultiSink.c: + + Fixed a core-dump problem caused when passing a null pointer to + XwcTextEscapement. +Text.c: + + Removed the resource adjustScrollbars. This resource was not used, and its + funcionality was not finished, and by now, it is not required. +TextAction.c: + + Does not call XLookpupString in InsertChar any more, but the new function + _XawLookupString (in XawIm.c) to work correclty with composed characters. +XawIm.c: + + Added the private function _XawLookupString, that just calls XmbLookupString, + or in case of any initialization error, XLookupString. + +-- xedit -- + The most important change is the addition of a new functionality, that allows + the user to navigate the file system, in a 'ls -a' like list widget, if + the file is not a directory it is loaded for edition, else, the list widget + is rebuilt with the contents of the selected directory. To test it, just + type: C-X d, or tab when 'finding a file'. To exit the dirwindow without + loading a file, type C-G or Escape. +Xedit-sample: + + Added more some resource entries, to use the new 'emacs dired like' feature. +Xedit.ad: + + Same as for Xedit-sample, but more important resource settings. +commands.c: + + The code now checks if the filename is a directory and calls the dirwindow + code in that case, when trying to open a file. + + Changed the function IsDir from static to global, to use it from xedit.c. + + Most of the code for the filesystem navigation window was added to this file. +util.c: + + Fixed a bug that was causing core dump due to passing garbage to XtGetValues + as the widget address. + + Added the code for managing the dirwindow and its relationship with the + text windows to this file. +xedit.c: + + Added the code for creation the dirwindow to this file. + + +#2638 2 Apr 1999 +-- Xaw -- + + Added xpm pixmaps support to the library. This time, it is required to + compile Xaw with -DUSE_XPM. + + If the xpm image has a mask, the widget will be automatically reshaped + to the pixmap mask. + + Changed the kill_ring code in TextAction.c to always end in a text block + of zero length, this way, it is easier to know when one traversed the + entire kill ring (it may be interesting to forget the undo sequences + while traversing the kill ring list). + +-- xedit -- + + Changed the Xedit.ad file to avoid overriding a translation that would + make the search window do not respond to WM_DELETE_WINODW messages. + + Fixed a core dump condition in the new code for listing files and + directories, due to deferencing a null pointer. + + +#2662 10 Apr 1999 +-- Xaw -- + + Corrected the problems gererated in my last patch. I was compiling with + -DUSE_XPM defined, and did'nt realize that the patch would not compile + without it. Just ifdef'ed again the code to avoid warnings or dead code. + +-- xedit -- + + Added a ispell interface to xedit. Sorry for not documenting enough about it + the man page, but here is a small explanation of the new funcionality: + Replace: Replace's the selected word. + All (right side of Replace button): Replaces all occurrences of the selected + word. + Undo: When this button is sensitive, allow undoing the last replace, + this is useful when doing a incorrect "Replace All" action. + Ignore: Ignore this word, and continues spell checking. + All (right side of Ignore button): Ignore any further ocurrences of the + selected word. + Add: Add's the selected word to the user's private dictionary. + Suspend: Go back to text edition, but does not kill the ispell process, + This is useful if you have a really big dictionary or slow + machine. I believe it is mostly useful to keep in memory + the words selected to be ignored, but that you don't want to + add to your private dictionary. + Close: Kill the ispell process, and go back to text edition. + Automatically saves the user's private dictionary. + When pressing the Add button, the word in the "Mispelled word:" field is + added to the user private dictionary (normally ~/.ispell_*). When pressing + the Replace button, the text in the "Replace with:" field is used. + If no word is selected in the "Suggestions:" field, this mean that the + selected word was not found in the ispell dictionary. + + +#2716 24 Apr 1999 +-- Xaw -- + + Minor changes to AsciiSrc.c to try to get more speed in the FindPiece + function. Xedit may become very slow when editing files bigger than 1M, + and I'm studing ways to get more speed in the Scan and FindPiece functions. + The FindPosition function in *Sink.c also can consume a lot of cpu time, + and may need some rework. + + Added submenus support to the SimpleMenuWidget. This is something essencial + to a widget toolkit. Just plugged in the code of a menu widget I wrote some + time ago. Xedit uses submenus now. To use it, set the resource menuName + of a SmeBSBObject to the name of the submenu. + + Added code for text justification to the TextWidget. To use the justification, + set the resources autoFill, leftColumn and rightColumn. If autoFill is set, + and leftColumn is smaller than rightColumn, an alternate code will be + used in the form-paragrpah action, normally triggered with M-Q. The values + for justification can be left, right, center and full. + + Added a overwrite mode to the TextWidget. The default translation is to + press the Insert key, that will toggle the overwrite mode. + + Made the TextWidget understand negative values for the multiply. This is + like the emacs feature, to indent text to the left. To set a negative value + to the multiply, just start the numeric sequence with a '-'. Like C-U -1. + + The code for justification added several new functions to TextAction.c. + Functions to tabify, untabify, get block boundaries, verify if a line + is completely blank, and strip excess of spaces. + + Added a indent action to the TextWidget. The default translation, only + used by xedit, is C-X Tab, did this way, to make it fully compatable with + emacs, but other translations can be used. The multiply value is used to + calculate the amount of spaces to move to the left or right. + + Corrected a very hard to find (and reproduce) bug in the undo code, that + would easily cause core dumps. The problem would happen when starting + editing exactly in the moment the redo automatically reverts to undo. + + Added translations for toggling the overwriting mode with the Insert key, + and to paste the selection with S-Insert. + +-- xedit -- + + Corrected all the known bugs in the ispell code (including a memory leak). + And added a compile time limit of 16 levels of undo, for all the actions, + that include Add, Ignore and Replace. 16 levels is more than enough, but + more than this can be done with the undo action, but then, only to revert + replaced text, to remove added words that the undo code forgot, it is + required to edit the personal dictionary file. The code now also understands + root/affix combinations, that ispell normally returns when using the + -m option. The ispell code should now also work when using the international + resource of the edit window. + + Added a new file, called options.c, that holds the code for the editMenu, + to enabling setting the wrap, autoFill, justify, leftColumn, rightColumn, + verticalScroll and horizontalScroll resources of the current edit window. + + +#2746 1 May 1999 +-- Xaw -- + + Reverted most of the #if NeedWidePrototypes definitions, only two + functions were kept, to not break some of the new features, but these + functions aren't called by any program: XawTextSinkDisplayText and + XawTextSinkClearToBackground. + + Rewrite of the functions *Sink.c:FindPosition() and FindDistance() to + try to get more speed. + + Reworked the function Text.c:_BuildLineTable, to correct some strange + code, and to avoid unecessary recalculations. + + Made negative values of the multiply work for all the actions, not only + for negative indentations. This makes the TextWidget behaviour more + compatable with emacs. + + Optimization of the new code for text justification, to avoid a call to + malloc on every char typped, when undo is enabled. + + Reorganized the offsets of the fields of the TextWidget, trying to make + xxgdb work again with the new Xaw code, but, unfortunately, the SimpleWidget + (a subclass of the TextWidget) have growed by 4 bytes (a XawDisplayList*) + added at the end of the structure, and xxgdb incorrectly reads the text.sink + field. Old xxgdb binaries dont work with the current code. + + Removed several XtIsSubclass checks in TextSrc.c. While those checks could + be useful for debugging, the functions are called so frequently that it is + a big waste of time for running programs. + +-- xedit -- + + Added/Changed some translations to work correctly when CapsLock and/or NumLock + are pressed. + + Fixed some bugs in the ispell code. The biggest bug was that it was not + correctly saving the Add'ed words in the user dictionary when pressing the + Close button. + + +#2764 8 May 1999 +-- Xaw -- + + Create two new private functions, to replace internally the public interfaces. + These two functions are XawTextSinkClearToBackground and + XawTextSinkDisplayText. These two functions use wide prototypes, and + are required to support text lines that are represented by more than + 32767 pixels. This was done to make sure that the public interfaces remain + 100% backwards compatible. + + Fixed the deferencing of a null pointer when the source object of a text + widget is not initialized. I noticed this problem when recompiling xcolorsel. + + Added a new type converter to Converters.c, that is Short -> String. + + Added a new compile time option, called NO_BIN_COMPAT_HACK. If defined, + it will break some programs that access private data. It only works with + programs that access private data structures, but don't subclassify any + widget. It fixed old binaries of chimera1, the Offix editor and xxgdb. + There is no way to fix old binaries of chimera2, xcolorsel and xmh, these + programs need to be recompiled. I would like to know of other programs that + became broken, to try to fix them with the NO_BIN_COMPAT_HACK option. + + Fixed some compile warnings, with shadowed, uninitialized and unused + variables. + + Fixed a inifite loop problem that could happen when the text widget window + was resized to a very small width. + + Reverted some of the text widget translations, to avoid conflicts when + setting the input focus and programs that do so. + +-- xedit -- + + Fixed a problem in the file-completion code, that would insert the partial + match in the incorrect position, if the cursor was not at the end of the + string. + + Changed ispell.c to use only one hash for ignored and added words. Also + changed the IspellSend function to not call itself recursively, what is + a big problem when spell checking big files that are correct or have too + few errors. + +-- editres -- + + Changed Editres.ad in several places, to try to avoid resource setting + problems. Most of them were changed to address more directly the resource, + and avoid confusion. Also, added some new resource settings to configure + the code I added to widgets.c. + + Changed widgets.c to make sure the resource setting dialog is allways + entirely in the screen, and if it does not fit, scrollbars will be created. + + +#2793 15 May 1999 +-- Xaw -- + + Changed AsciiSrc.c:LoadPieces to load the file incrementally, instead of + allocating a big buffer. + + Added several new functions to DisplayList.c. Almost all gc and painting + related functions were mapped to displayList functions. There are + several optimizations that can yet be done to the displayList code, and + I'm working on it. That code is clearly not finished yet, but is stable. + Also, changed some functions to be more exigent with it's parameters, + because it is better to receive a warning message than see the program + core dumping. The functions are documented in Xaw.man. + + Corrected a problem in the SimpleMenu code, to make the sub menus popup + more 'visually' correct, when popping up in the left side. + + Added a optimization in Text.c, to avoid unnecessarily recalculating + the line and column number when scrolling text. A big speed up should + be seen when scrolling large files. + + Modified all code that expected TAB_SIZE to be equal to 8, to read the + TextSink resources, and work properly with whatever value the program + had set to the tab stops. + + Fixed a very bad bug in the form-paragraph function. It was very hard + to find because I was looking at the wrong places. If the text was + allready formatted, or did not need formatting, the code was not + reenabling undo, making the undo/redo behaviour imprevisible. + +-- xedit -- + + Added Xedit-color.ad file, to show some of the new features of Xaw. + Tried to keep it simple, but since it uses gradients, maybe it should + better be called Xedit-TrueColor. The better way to see the functionality + of this file is (if you don't have it already) add to your .Xdefaults: +#ifdef COLOR +*customization: -color +#endif + and make sure xrdb parses it. + + Changed a bit Xedit.ad, to work properly when Caps Lock is pressed. + + Several changes to ispell.c. It should run very faster now, because + the code keeps information about words already ignored or correct + in the xedit side, instead of asking ispell every time. Added also + a terseMode resource, and made the interface ask for user interaction + allways ispell does not say the word is completely correct; the + terseMode resource makes ispell itself decide what words are correct + or not. + +-- editres -- + + Small patch to Edit-col.ad, to use a default text cursor color of 'Azure' + in text fields, instead of the default 'black'. + + +#2811 22 May 1999 +-- Xaw -- + + Removed the 'NO_NUMERIC_HACK' preprocessor definition, and renamed the + 'doing_numeric_hack' field of the text widget to 'numeric'. + + Changed the code to always create the horizontal scrollbar, if requested. + + Small changes to TextPop.c, to automatically scroll horizontally the + text window when the text found in a search/replace action is not visible. + + Added a optimization when editting large files, to rebuild the line table + if the region containing the text being added/replaced overlaps the lt.top + field of the text widget. + + Changed the undo code to also merge text typed when overwrite mode is + active. The new behaviour is not like emacs (that generates a undo step + for every character), but uses less memory, making only one undo/redo step. + +-- xedit -- + + Added a new file, hook.c that is intended to be used for the addition of + some new features to xedit, like auto indentation of program files. The + first feature added is the 'autoReplace' resource, described in the xedit + man page. + + Corrected a bug in ispell.c, that would make the code alocate lots of + memory unnecessarily, due to an uninitialized variable. Thanks to David + Dawes that found the bug. The bug was not in 3.9Pn, but the solution in + the later release was not completely correct. + + +#2834 29 May 1999 +-- Xaw -- + + Added a ChangeSensitive function to Command.c, to avoid it creating an + incorrect insensitive border if the button is set. This is a side effect of + the function XawCommandToggle I added some time ago. The solution for the + problem is not very elegant, since it copies almost verbatim the code from + Simple.c, but it works as expected. + + Moved some calls to _XawTextSetLineAndColumnNumber in Text.c to other places, + to make sure it is safe to change the text when the positionCallback is + called (like what is done by the new xedit file hook.c). + + Another optimization was added to the undo/redo code. Now it also merge + erases, needing yet less memory for undo, and this way, generating less + undo/redo steps. + + Removed the default translation to call the toggle-overwrite action from + TextTr.c. Only the xedit edit windows calls this translation now, instead of + every text widget. + +-- xedit -- + + Changed the auto replace feature to be a bit more easier to use. The new + behaviour is almost identical, but if the user types some text, and it is + auto replaced, only one undo step is enough to correct it. Example: + 1) user types 'nto.' + 2) text is auto replaced by 'not.' + 3) user call undo action + 4) text is converted to 'nto.' + It should be a very infrequent problem, but makes the xedit behaviour + identical to a "well known text editor", from where this feature was borrowed. + + Added a 'Check' button to the ispell interface. This button allows + checking the word in the text field. This feature was borrowed from the spell + checking interface of the Netscape html editor. + + The ispell checking interface now also asks for user interaction if there are + two identical words togheter. + + Added a status bar to the ispell interface, to give feedback to the user + about what is happening. + + Added some new resources, to let easier customization of the ispell status + bar strings. The new resources are documented in xedit.man. + +#2849 5 Jun 1999 +-- Xaw -- + + Add a OLDXAW define, to enable building a binary compatible version with + 6.1, and changes to the Imakefile, to try to keep the changes only in Xaw. + I hope it can be removed in the future. + + Add a XawVendor define, with the value "XFree86". If this is not a good + idea, please correct it an let me know. + + Add a XawVersion define. The value for the new xaw is 7000L, and for the + compatible one is 6700L (same comments as for the XawVendor define). + + Bug fixes to the undo/redo code, and code to merge erases generated by + ^H and ^D. Also, if the cursor is moved, it stops merging the text typped + in the undo buffer. + + Bug fixes to the Form widget geometry management code, to work correctly + when child widgets are removed or added at run time. + + Xaw now links with XPM by default, and the config files where changed to + enable newly compiled programs to do so. + + Added 16 pad bytes to every widget, to try to avoid binary compatability + problems in the future. + + Added a displayList resource to the Tree Widget. + + Added the functions XawTextGetSink and XawTextLastPosition, to enable a + public way to get the <TextWidget>->text.sink and <TextWidget>->text.lastPos, + since these are the most commonly private fields the programs access in + the text widget. + + Added the actions 'capitalize-word', 'donwcase-word' and 'upcase-word' to + TextAction.c. The bindings are the same as of Emacs (and the way it works). + + Corrected some problems with negative values of the <TextWidget>->text.mult. + +-- xedit -- + + Correct possible problem in the file hook.c, when interpreting the auto + replace list, that is, it was not checking the buffer size when finding + the '\' character. + + Updates for the configuration files. + + Added a 'Look' button the the ispell interface, that will by default run + "/usr/bin/bin/egrep -i '^<VALUE OF TEXT FIELD>.*$' /usr/share/dict/words" + and put up to 256 returned words in the ispell list. The behavior is + almost identical to the one in the terminal interface of ispell. + + The ispell interface works correctly with aspell now. + + Added some resources and a popup to enable changing the dictionaries in + run time. + + Added a toggle button to the ispell interface to allow changing the terse + mode in run-time. + + Added a 'Uncap' button, to allow adding an uncapitalized word to the + private dictionary, and enough code to do the capitalization checks inside + of xedit (to enable undo actions). + + Added a "text mode" and a "html mode". The html mode is not yet completely + finished. It must work correctly with some html specific things like + converting internally "á" to "á" and so on. I'm planning also, at + least a nroff mode too. + + The wordChars resource is set by dictionary now. + To set the word chars for the br dictionary, write something like: + *ispell*options.dictionaries.br.wordChars: <VALUE> + or + *ispell*br.wordChars: <VALUE> + or simply + *ispell*wordChars: <VALUE> + + The skipLines resource is set only for the text mode now. + To set it, write something like: + *ispell*options.formats.text.skipLines: <VALUE> + or + *ispell*options*text.skipLines: <VALUE> + or simply + *ispell*skipLines: <VALUE> + + +#2877 12 Jun 1999 +-- Xaw -- + + Note: The compatible old version of Xaw is not fully compatible. There + a few things that are not equal to the standard old Xaw. These are: + + The cursor code in the *Sink.c files is not identical, and the + field insertCursorOn (type Pixmap) was replaced by the field + cursor_position (type XawTextPosition). + + There are some changes in TextP.h, that include changes to the fields: + options -> left_margin + unrealize_callbacks -> pad1 + updateFrom -> update + updateTo -> pad2 + numranges -> pad3 + maxranges -> from_left + copy_area_offsets -> pad4 + + The text window does not increase its size when text is typed past + the end of the window, instead of it, it is automatically scrolled + horizontally, but this may not be enough to every usage of this + feature; xmh uses that code to make the text widget auto resize + warning popup widgets. I dont know what is better in this case, + if re-enabling the auto resize code of changing xmh to use label + widgets in the warning popups. + It is very unlikely that exists code that will have problems with these + changes in the fields of the TextWidget and the *SinkObject, but if any + code that has trouble with it exists, I will promptly make the required + changes to correct it (at least for the compatible version of Xaw). + + Several optimizations for the code to redisplay the text window in the + TextWidget. Including fixes for bugs in the XawTextScroll function, and + making it really works. Previous versions of the library have made this + function ineffective, because it was always redrawing everything when + the text window was scrolled. The optimizations should be more noticeable + when running some application that uses the TextWidget (like xedit) on + slow hardware, or over slow connections. + + Corrections for the FormWidget geometry management code, to work correctly + in the old version of Xaw, and some bug fixes for the new Xaw. Also added + 8 pad bytes to the FormConstraintsPart structure, to have space for extra + information on possible future optimizations for the FormWidget geometry + management code. + + Some fixes for the OLDXAW define in the SimpleMenuWidget code, that was + not hiding some of the new fields introduced in the new Xaw code. + + Some corrections for the code handling the necessity of having scrollbars + in the text widget, and bug fixes for cases where the scrollbars were not + being updated when the text window contents were changed. + + Re-enabled code to also process GraphicsExpose events in the text code. It + became required due to the optimizations in the text redisplay code. + + Several fixes in TextAction.c, for symbols that were not being included + in the compatible version of the library, and for symbols that were being + included with no need. + + Fixes for the form-paragraph action, in the old Xaw code. + +-- xedit -- + + Some bug fixes for the ispell undo code, to avoid deferencing a NULL pointer + in the function IspellCheckUndo. + + Added code to handle correctly &<VALUE>; in ispell.c, when using the html + mode. + + Fixed some compile time warnings, and updated the code for setting the + scrollbars in options.c. + + +#2899 19 Jun 1999 +-- Xaw -- + + Changed all the 'char pad[<number>]' to 'XtPointer pad[<number>/4]' to + make sure 64 bit machines will not have binary compatibility problems before + the 32 bit ones. + + Added a new static function 'WritePiecesToFile' to AsciiSrc.c, to avoid + allocation of temporary memory. This is useful when editing very large + files (I have some people using xedit on text files that can have up to + 80,000 lines). + + Added more some optimizations to AsciiSrc.c:Scan, to try to get the maximum + speed of this function. + + Added a new function to the displayList's, called 'image', that will tile + pixmaps on the widget. It is documented in Xaw.man. + + Several widget classes did not have a 'extension' field. I added it to them. + The first usage of this field that I'm planning is to extend the *Src and + *Sink objects to handle formatted text, and add text properties, like + foreground, background, font and so on. + + Fixed a bug in MultiSrc.c, that was crashing Xaw after the first character + was typed, or if text was removed. + + Some minor changes to SimpleMenu.c, to work properly with very large menus. + + Fixed some bugs that were caused by my previous optimizations of the text + redisplay code. + + Bug fixes and optimizations to TextPop.c, there were some cases that the + function XawTextDisableRediplay was being called, but XawTextEnableRedisplay + was not being called later because of a error condition (the error + conditions were only warnings). ++ Updates to Xaw.man. + +-- xedit -- + + Fixed a memory leak when freeing list widget strings. The code was not + releasing the memory of the string at offset 0, in the list. + + Changed the way the ispell undo code handles the terse mode, to not need + to make the toggle button insensitive. + + Updated xedit.man. + + +#2932 26 Jun 1999 +-- Xaw -- + + Added a new tip resource to the SimpleWidget. This may also be seen as + a test of the binary compatibility issues. Besides of being a new feature, + it cannot cause problems with old binaries, because the code is only + called if the tip resource is set to any SimpleWidget subclass. If the + tip resource is set or reset, the SimpleWidget code will call one of the + two new functions XawTipEnable or XawTipDisable. + + Added 3 new files: Tip.c, Tip.h and TipP.h. These files are used only + by the new Xaw. + + Updates to Xaw.man, including a problem with accented characters on SunOS. + +-- xedit -- + + Added resource configurations to show the new tip code in Xaw. + + Some fixes to ispell.c, to make it more previsible/user-friendly. + + Fixes xedit.man to avoid problems with accented characters. + + +#2964 3 Jul 1999 +-- Xaw -- + + Fix for problem found in the search/replace dialog when using splitted + windows in xedit. + + Added initialization for the display_list field of the Tree widget. + +-- xedit -- + + Fixed some problems in the undo code of ispell interface. + + +#2999 10 Jul 1999 +-- Xaw -- + + Added code to check the return value of XAllocColor and XAllocNamedColor in + Pixmap.c. + + Reverted back some code, and did a carefull review of the code in TextPop.c + to avoid the possibility of calling XawTextDisableRedisplay, and not calling + XawTextEnableRedisplay later (due to errors or end of file reached). + + Added code to TextSrc.c, to use two static variables, that represent a new + line in 8 bits and wchar_t, to avoid allocating memory in the undo buffers + to store only a new line. + + Small change in the behavior of the Tip widget, to not unmap the tip window + when the cursor is moved. + +-- Xmu -- + + Fixed a bug and a typo in the XmuToupper macro. + +-- xedit -- + + Small update to the Xedit-sample file. + + Fixed a bug in the ispell code that checks for repeated words. + + +#3122 14 Aug 1999 +-- Xaw -- + + Mixed fonts and colors can be used in the text widget (currently only + in the Ascii*Object). + + Added the XawTextAnchor, XawTextEntity, XawTextProperty, XawTextPropertyList, + XawTextPaintStruct, XawTextPaintList and XawTextPropertyInfo structures to + Xaw, to be used in the new text code. + + Added the functions XawTextSourceAddAnchor, XawTextSourceNextAnchor, + XawTextSourcePrevAnchor, XawTextSourceRemoveAnchor and + XawTextSinkConvertPropertyList, that probably should not be used outside of + Xaw. + + Added the functions XawTextSourceFindAnchor, XawTextSourceAnchorAndEntity, + XawTextSourceAddEntity, XawTextSourceClearEntities and XawTextSinkGetProperty + that are probably the ones that should be most used in programs. + + Italic fonts should be always displayed correctly. + + The text widget cursor is now displayed with a gc with the Xor function, to + avoid unnecessary computation/redrawing. + + Most changes were done in the {Ascii,Text}{Src,Sink}Object, but the text + widget was also a bit modified for things like automatically changing the + number of lines in the line table when needed. + +-- Xmu -- + + Fixed bug in Clip.c, that could cause a SEGV. + +-- xedit -- + + Added the file c-mode.c, to interface with the new Xaw text code, and show + what can be done when interfacing that new code. + + Added the necessary code to util.c and options.c to let the user select + if he or she wants to use the color/font syntax highlight in the C/C++ mode. + + +# 26 Aug 1999 + +--Xaw-- + + Added initial support for two new XawTextEntity attributes, that enable + hidden text and replaced text. This initial support was the minimum + required to get the new html mode in xedit working. A lot of code does + math with text positions, and became broken with the addition of these + two attributes. Since only code that knows about these two attributes + should use it, it is only a question to fix the remaining code in + Xaw/xedit. + + Bug fixes to AsciiSink.c:PreparePaint to work correctly with tabs and + the two new entity attributes. + + Disabled the translation "c<Key>q,<Key>Tab" of the search/replace popup. + This action is already done by the translation "<Ctrl>Q,<Key>" that I added + to TextTr.c. Disabling that translation has the advantage that now it + is possible to replace ^Ms by nothing. + + Added some new functions to TextSink.c. The functions XawTextSinkCopyProperty, + XawTextSinkAddProperty and XawTextSinkCombineProperty are candidates to being + public in the future, but, there is a problem when using + XawTextSinkCombineProperty, that requires the AsciiSinkObject having the + correct XawTextPropertyList, what can generate a "chicken and egg" like + problem (I did some hacks in xedit to have the first html-mode version + working). + + Added several new flags to the XawTextProperty attributes, and a new field, + called xlfd_mask. + + Some bug fixes to XawTextSourceReplace and to the code to manage the + XawTextAnchor e XawTextEntity structures. The form-paragraph, called with + M-Q does several consecutive text changes, and was very useful to find bugs. + + The flag XAW_TENTF_REPLACE is a hack for XawTextSourceAddEntity currently. + The function XawTextSourceAddEntity will probably change its parameters + to receive a structure pointer, or a pointer parameter. + +--xedit-- + + Fixed some bugs in c-mode.c. Again, this patch fixes all the bugs I have + found. + + Added the html-mode.c file to xedit. The html-mode is in its initial steps. + It is not usable yet, but should not core-dump or leak memory (unless you + try to edit the file, then, I cannot say what will happen). The html mode + should be used only to see a rendered version of the file, but, there are + several markups not implemented. To be usable, it must yet understand at + least <ul>, <ol>, <li>, <dl>, <dd>, <hr> and the table tags. + + + +$XFree86: xc/lib/Xaw/Changelog,v 3.31 1999/08/15 13:00:31 dawes Exp $ diff --git a/packaging/libXaw.spec b/packaging/libXaw.spec new file mode 100644 index 0000000..57d67eb --- /dev/null +++ b/packaging/libXaw.spec @@ -0,0 +1,80 @@ +Summary: X Athena Widget Set +Name: libXaw +Version: 1.0.11 +Release: 1 +License: MIT +URL: http://www.x.org +Group: System Environment/Libraries + +Source0: %{name}-%{version}.tar.gz + +BuildRequires: pkgconfig(xproto) pkgconfig(x11) pkgconfig(xt) +BuildRequires: pkgconfig(xmu) pkgconfig(xpm) pkgconfig(xext) +BuildRequires: pkgconfig(xorg-macros) +# Required by the configury. +BuildRequires: ed +BuildRequires: xorg-x11-xutils-dev + +%description +Xaw is a widget set based on the X Toolkit Intrinsics (Xt) Library. + +%package devel +Summary: Development files for %{name} +Group: Development/Libraries +Provides: libxaw-devel +Requires: %{name} = %{version}-%{release} +Requires: pkgconfig +Requires: pkgconfig(xproto) pkgconfig(xmu) pkgconfig(xt) pkgconfig(xpm) + +%description devel +X.Org X11 libXaw development package + +%prep +%setup -q + +%build +export CFLAGS="${CFLAGS} $RPM_OPT_FLAGS -Os" +%reconfigure \ + LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed" \ + --disable-xaw8 --disable-static \ + --disable-xaw6 +make %{?jobs:-j%jobs} + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p %{buildroot}/usr/share/license +cp -af COPYING %{buildroot}/usr/share/license/%{name} +make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" +rm -f $RPM_BUILD_ROOT%{_libdir}/*.la + +%remove_docs + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +/usr/share/license/%{name} +#%doc COPYING README ChangeLog +%{_libdir}/libXaw.so.7 +%{_libdir}/libXaw7.so.7 +%{_libdir}/libXaw7.so.7.0.0 + +%files devel +%defattr(-,root,root,-) +%dir %{_includedir}/X11/Xaw +%doc COPYING +%{_includedir}/X11/Xaw/*.h +# FIXME: Is this C file really supposed to be here? +%{_includedir}/X11/Xaw/Template.c +%{_libdir}/libXaw.so +%{_libdir}/libXaw7.so +%{_libdir}/pkgconfig/xaw7.pc +#%{_mandir}/man3/*.3* +#%dir %{_docdir}/%{name}-%{version}-%{release} +#%{_docdir}/%{name}-%{version}-%{release}/*.xml +#{_docdir}/%{name}-%{version}-%{release}/%{name}.html +#{_docdir}/%{name}-%{version}-%{release}/%{name}.txt diff --git a/specs/AsciiSink.xml b/specs/AsciiSink.xml new file mode 100644 index 0000000..aba588b --- /dev/null +++ b/specs/AsciiSink.xml @@ -0,0 +1,141 @@ +<sect1 id="Ascii_Sink_Object_and_Multi_Sink_Object"> +<title>Ascii Sink Object and Multi Sink Object + + + + + + + + + + + + +Application Header file <X11/Xaw/AsciiSink.h> + +Class Header file <X11/Xaw/AsciiSinkP.h> + +Class asciiSinkObjectClass + +Class Name AsciiSink + +Superclass TextSink + + + + +The AsciiSink or MultiSink object is used by a text widget to render the text. +Depending on its international resource, a +AsciiText widget will create one or the other of these when the AsciiText +itself is created. Both types are nearly identical; the following discussion +applies to both, with MultiSink differences noted only as they occur. +The AsciiSink +will display all printing characters in an 8 bit font, along with handling Tab +and Carriage Return. The name has been left as ``AsciiSink'' for compatibility. +\fIThe MultiSink will display all printing characters in a font set, along with +handling Tab and Carriage +Return.\fP The source object also reports the text window metrics to the +text widgets. + + +Resources + + +When creating an AsciiSink object instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + background + Background + Pixel + + XtDefaultBackground + + + destroyCallback + Callback + XtCallbackList + + NULL + + + displayNonprinting + Output + Boolean + + True + + + echo + Output + Boolean + + True + + + font + Font + XFontStruct* + + XtDefaultFont + + + fontSet + FontSet + XFontSet + + XtDefaultFontSet + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + _ + + + + + +This resource is retrieved by the AsciiSink instead of being copied +from the Text widget. + + + + + + +The text font to use when displaying the string. +(This resource is present in the AsciiSink, but not the MultiSink.) + + + +The text font set to use when displaying the string. +(This resource is present in the MultiSink, but not the AsciiSink.) + + + diff --git a/specs/AsciiSource.xml b/specs/AsciiSource.xml new file mode 100644 index 0000000..b3ca6da --- /dev/null +++ b/specs/AsciiSource.xml @@ -0,0 +1,368 @@ + +Ascii Source Object and Multi Source Object + + + + + + + + + + + + +Application Header file <X11/Xaw/AsciiSrc.h> or <X11/Xaw/MultiSrc.h> + +Class Header file <X11/Xaw/AsciiSrcP.h> or <X11/Xaw/MultiSrcP.h> + +Class asciiSrcObjectClass or multiSrcObjectClass + +Class Name AsciiSrc or MultiSrc + +Superclass TextSource + + + + +The AsciiSrc or MultiSrc object is used by a text widget to read the text from a +file or string in memory. Depending on its international resource, an +AsciiText widget will create one or the other of these when the AsciiText +itself is created. Both types are nearly identical; the following discussion +applies to both, with MultiSrc differences noted only as they occur. + + + +The AsciiSrc understands all Latin1 characters plus Tab +and Carriage Return. \fIThe MultiSrc understands any set of character sets that +the underlying X implementation's internationalization handles.\fP + + + +The AsciiSrc can be either of two types: XawAsciiFile +or XawAsciiString. + + + +AsciiSrc objects of type XawAsciiFile read the text from a file and +store it +into an internal buffer. This buffer may then be modified, provided the +text widget is in the correct edit mode, just as if it were a source of +type XawAsciiString. Unlike R3 and earlier versions of the AsciiSrc, +it is now possible to specify an editable disk source. The file is not +updated, however, until a call to is made. When the +source is in this mode the useStringInPlace resource is ignored. + + + +AsciiSrc objects of type XawAsciiString have the text buffer +implemented as a string. +\fIMultiSrc objects of type XawAsciiString have the text buffer +implemented as a wide character string.\fP +The string owner is responsible for allocating and managing storage for the +string. + + + +In the default case for AsciiSrc objects of type XawAsciiString, +the resource useStringInPlace is false, +and the widget owns the string. The initial value of the +string resource, and any update made by the application +programmer to the string resource with , is copied +into memory private to the widget, and managed internally by the widget. +The application writer +does not need to worry about running out of buffer space +(subject to the total memory available to the application). +The performance does not decay linearly as the buffer grows +large, as is necessarily the case when the text buffer is used +in place. The application writer must use to +determine the contents of the text buffer, which will return +a copy of the widget's text buffer as +it existed at the time of the call. This copy +is not affected by subsequent updates to the text buffer, i.e., +it is not updated as the user types input into the text buffer. +This copy is freed upon the next call to XtGetValues to +retrieve the string resource; however, to conserve memory, +there is a convenience routine, , allowing the +application programmer to direct the widget to free the copy. + + + +When the resource useStringInPlace is true and the AsciiSrc object +is of type XawAsciiString, the application +is the string owner. The widget will take the value +of the string resource as its own text buffer, and the length +resource indicates the buffer size. In this case +the buffer contents change as the user types at the widget; +it is not necessary to call on the string +resource to determine the contents of the buffer-it will +simply return the address of the application's implementation +of the text buffer. + + +Resources + + +When creating an AsciiSrc object instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + callback + Callback + XtCallbackList + + NULL + + + dataCompression + DataCompression + Boolean + + True + + + destroyCallback + Callback + Callback + + NULL + + + editType + EditType + EditMode + + XawtextRead + + + length + Length + Int + A + length of string + + + pieceSize + PieceSize + Int + + BUFSIZ + + + string + String + String + + NULL + + + type + Type + AsciiType + + XawAsciiString + + + useStringInPlace + UseStringInPlace + Boolean + + False + + + _ + + + + + + + + + + + + + + + + +Convenience Routines + + +The AsciiSrc has a few convenience routines that allow the +application programmer quicker or easier access to some of the +commonly used functionality of the AsciiSrc. + + +Conserving Memory + + +When the AsciiSrc widget is not in useStringInPlace mode +space must be allocated whenever the file is saved, or the string is +requested with a call to . This memory is allocated on the +fly, and remains valid until the next time a string needs to be allocated. +You may save memory by freeing this string as soon as you are done +with it by calling . + + + void XawAsciiSourceFreeString + Widget w + + + + + + + w + + + +Specifies the AsciiSrc object. + + + + + + + +This function will free the memory that contains the string pointer returned +by . This will normally happen automatically when +the next call to occurs, or when the widget is destroyed. + + + +Saving Files + + +To save the changes made in the current text source into a file use +. + + + Boolean XawAsciiSave + Widget w + + + + + + + w + + + +Specifies the AsciiSrc object. + + + + + + + + returns True if the save was successful. +It will update the file named in the string resource. +If the buffer has not been changed, no action will be taken. This function +only works on an AsciiSrc of type XawAsciiFile. + + + + +To save the contents of the current text buffer into a named file use +. + + + Boolean XawAsciiSaveAsFile + Widget w + String name + + + + + + + w + + + +Specifies the AsciiSrc object. + + + + + + name + + + +The name of the file to save the current buffer into. + + + + + + + +This function returns True if the save was successful. + will work with a buffer of either type +XawAsciiString or type XawAsciiFile. + + + +Seeing if the Source has Changed + + +To find out if the text buffer in an AsciiSrc object has changed +since the last time it was saved with or queried + +use . + + + Boolean XawAsciiSourceChanged + Widget w + + + + + + + w + + + +Specifies the AsciiSrc object. + + + + + + + +This function will return True if the source has changed since +the last time it was saved or queried. The internal change flag is +reset whenever the string is queried via or the +buffer is saved via . + + + + + diff --git a/specs/AsciiText.xml b/specs/AsciiText.xml new file mode 100644 index 0000000..156e0c0 --- /dev/null +++ b/specs/AsciiText.xml @@ -0,0 +1,450 @@ + +Ascii Text Widget + + + + + + + + + + + + +Application Header file <X11/Xaw/AsciiText.h> + +ClassHeader file <X11/Xaw/AsciiTextP.h> + +Class asciiTextWidgetClass + +Class Name Text + +Superclass Text +Sink Name textSink +Source Name textSource + + + + + +For the ease of internationalization, the AsciiText widget class name has not +been changed, although it is actually able to support non-ASCII locales. +The AsciiText widget is really a collection of smaller parts. It +includes the Text widget itself, a ``Source'' (which supports memory management), +and a ``Sink'' (which handles the display). There are currently two supported +sources, the AsciiSrc and MultiSrc, and two supported sinks, the AsciiSink and + + + + +MultiSink. Some of +the resources listed below are not actually resources of the +AsciiText, but belong to the associated source or sink. This is +is noted in the explanation of each resource where it applies. When +specifying these resources in a resource file it is necessary to use +*AsciiText*resource_name instead of +*AsciiText.resource_name, since they actually belong to the +children of the AsciiText widget, and not the AsciiText widget itself. +However, these resources may be set directly on the AsciiText widget at +widget creation time, or via . + + +Resources + + +When creating an AsciiText widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + autoFill + AutoFill + Boolean + + False + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + bottomMargin + Margin + Position + + 2 + + + callback + Callback + XtCallbackList + + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cursor + Cursor + Cursor + + XC_xterm + + + cursorName + Cursor + String + + NULL + + + dataCompression + DataCompression + Boolean + + True + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + displayCaret + Output + Boolean + + True + + + displayNonprinting + Output + Boolean + + True + + + displayPosition + TextPosition + XawTextPosition + + 0 + + + echo + Output + Boolean + + True + + + editType + EditType + XawTextEditType + + XawtextRead + + + font + Font + XFontStruct* + + XtDefaultFont + + + fontSet + FontSet + XFontSet + + XtDefaultFontSet + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + Font height + margins + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + insertPosition + TextPosition + int + + 0 + + + international + International + Boolean + C + False + + + leftMargin + Margin + Dimension + + 2 + + + length + Length + int + A + length of string + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + pieceSize + PieceSize + XawTextPosition + + BUFSIZ + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + resize + Resize + XawTextResizeMode + + XawtextResizeNever + + + rightMargin + Margin + Position + + 2 + + + screen + Screen + Screen + R + Parent's Screen + + + scrollHorizontal + Scroll + XawTextScrollMode + + XawtextScrollNever + + + scrollVertical + Scroll + XawTextScrollMode + + XawtextScrollNever + + + selectTypes + SelectTypes + XawTextSelectType* + + See above + + + sensitive + Sensitive + Boolean + + True + + + string + String + String + + NULL + + + textSink + TextSink + Widget + + An AsciiSink + + + textSource + TextSource + Widget + + An AsciiSrc + + + topMargin + Margin + Position + + 2 + + + translations + Translations + TranslationTable + + See above + + + type + Type + XawAsciiType + + XawAsciiString + + + useStringInPlace + UseStringInPlace + Boolean + + False + + + width + Width + Dimension + + 100 + + + wrap + Wrap + WrapMode + + XawtextWrapNever + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + + diff --git a/specs/Box.xml b/specs/Box.xml new file mode 100644 index 0000000..692d7d2 --- /dev/null +++ b/specs/Box.xml @@ -0,0 +1,346 @@ + +Box Widget + + + + + + + + + + +Application Header file <X11/Xaw/Box.h> + +Class Header file <X11/Xaw/BoxP.h> + +Class boxWidgetClass + +Class Name Box + +Superclass Composite + + + + + +The Box widget provides geometry management of arbitrary widgets in a +box of a specified dimension. The children are rearranged when +resizing events occur either on the Box or its children, or when +children are managed or unmanaged. The Box widget always attempts to +pack its children as tightly as possible within the geometry allowed by +its parent. + + + +Box widgets are commonly used to manage a related set of buttons and +are often called ButtonBox widgets, but the children are not +limited to buttons. The Box's children are arranged on a background that +has its own specified dimensions and color. + + +Resources + + +When creating a Box widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + children + ReadOnly + WidgetList + R + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + height + Height + Dimension + A + see Layout Semantics + + + hSpace + HSpace + Dimension + + 4 + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + numChildren + ReadOnly + Cardinal + R + 0 + + + orientation + Orientation + Orientation + + XtorientVertical + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + vSpace + VSpace + Dimension + + 4 + + + translations + Translations + TranslationTable + + NULL + + + width + Width + Dimension + A + see Layout Semantics + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + _ + + + + + + + + + + + + + + + + + + + + hSpace + + + + + + + + + + + vSpace + + + +The amount of space, in pixels, to leave between the children. This +resource specifies the amount of space left between the outermost +children and the edge of the box. + + + + + + + + orientation + + + +Specifies whether the preferred shape of the box (i.e. the result +returned by the query_geometry class method) is tall and narrow +XtorientVertical or short and wide XtorientHorizontal. + + + +When the Box is a child of a parent which enforces width constraints, it +is usually better to specify XtorientVertical (the default). +When the parent enforces height constraints, it is usually better to +specify XtorientHorizontal. + + + + + + + + + + + + +Layout Semantics + + + +Each time a child is managed or unmanaged, the Box widget will attempt +to reposition the remaining children to compact the box. Children are +positioned in order left to right, top to bottom. The packing +algorithm used depends on the orientation of the Box. + + + + XtorientVertical + + + + +When the next child does not fit on the current row, a new row is +started. If a child is wider than the width of the box, the box will +request a larger width from its parent and will begin the layout +process from the beginning if a new width is granted. + + + + + + XtorientHorizontal + + + + +When the next child does not fit on the current row, the Box widens if +possible (so as to keep children on a single row); otherwise a new row is +started. + + + + + + + +After positioning all children, the Box widget attempts to shrink its +own size to the minimum dimensions required for the layout. + + + + diff --git a/specs/CH1.xml b/specs/CH1.xml new file mode 100644 index 0000000..8d913b8 --- /dev/null +++ b/specs/CH1.xml @@ -0,0 +1,725 @@ + +Athena Widgets and The Intrinsics + +The X Toolkit is made up of two distinct pieces, the Xt Intrinsics and a +widget set. The Athena widget set is a sample implementation of a +widget set built upon the Intrinsics. In the X Toolkit, a widget is the +combination of an X window or subwindow and its associated input and +output semantics. + + +Because the Intrinsics provide the same basic functionality to all widget +sets it may be possible to use widgets from the Athena widget set with +other widget sets based upon the Intrinsics. Since widget sets may also +implement private protocols, all functionality may not be available when +mixing and matching widget sets. For information about the Intrinsics, see +the X Toolkit Intrinsics - C Language Interface. + + +The Athena widget set is a library package layered on top of the Intrinsics +and Xlib that provides a set of user interface tools sufficient to build +a wide variety of applications. This layer extends the basic +abstractions provided by X and provides the next layer of functionality +primarily by supplying a cohesive set of sample widgets. Although the +Intrinsics are a Consortium standard, there is no standard widget set. + + + +To the extent possible, the Intrinsics are "policy-free". The application +environment and widget set, not the Intrinsics, define, implement, and +enforce: + + + + Policy + Consistency + Style + + + +Each individual widget implementation defines its own policy. The X Toolkit +design allows for, but does not necessarily encourage, the free mixing +of radically differing widget implementations. + + + +Introduction to the X Toolkit + + + + + + +The X Toolkit provides tools that simplify the design of +application user interfaces in the X Window System programming environment. +It assists application programmers by providing a set of common +underlying user-interface functions. It also lets widget programmers +modify existing widgets, by subclassing, or add new widgets. By using +the X Toolkit in their applications, programmers can present a similar +user interface across applications to all workstation users. + + + +The X Toolkit consists of: + + + + +A set of Intrinsics functions for building widgets + + + + +An architectural model for constructing widgets + + + + +A widget set for application programming + + + + + +While the majority of the Intrinsics functions are intended +for the widget programmer, +a subset of the Intrinsics functions are to be used by application programmers +(see X Toolkit Intrinsics - C Language Interface). +The architectural model lets the widget programmer design new widgets +by using the Intrinsics and by combining other widgets. +The application interface layers built on top of the X Toolkit include a +coordinated set of widgets and composition policies. +Some of these widgets and policies are specific to a single +application domain, and others are common to a variety of +applications. + + + +The remainder of this chapter discusses the X Toolkit and Athena widget set: + + + + +Terminology + + + + +Model + + + + +Conventions used in this manual + + + + +Format of the Widget Reference Chapters + + + + + +Terminology + + + + + + + + +In addition to the terms already defined for X programming (see +Xlib - C Language Interface), +the following terms are specific to the Intrinsics and Athena widget set +and used throughout this document. + + + +Application programmer + + + + + +A programmer who uses the X Toolkit to produce an application user interface. + + + + + +Child + + + + + +A widget that is contained within another "parent" widget. + + + + + +Class + + + + + +The general group to which a specific object belongs. + + + + + +Client + + + + + +A function that uses a widget in an application or for composing +other widgets. + + + + + +FullName + + + + + +The name of a widget instance appended to the full name of its parent. + + + + + +Instance + + + + + +A specific widget object as opposed to a general widget class. + + + + + +Method + + + + + +A function or procedure implemented by a widget class. + + + + + +Name + + + + + +The name that is specific to an instance of a widget for a given client. +This name is specified at creation time and cannot be modified. + + + + + +Object + + + + + +A data abstraction consisting of private data and private and public +functions that operate on the private data. +Users of the abstraction can interact with the object only through calls +to the object's public functions. +In the X Toolkit, +some of the object's public functions are called directly by the application, +while others are called indirectly when the application calls the common +Intrinsics functions. +In general, if a function is common to all widgets, +an application uses a single Intrinsics function to invoke the function for all +types of widgets. +If a function is unique to a single widget type, +the widget exports the function. + + + + + +Parent + + + + + +A widget that contains at least one other ("child") widget. +A parent widget is also known as a composite widget. + + + + + +Resource + + + + + +A named piece of data in a widget that can be set by a client, +by an application, or by user defaults. + + + + + +Superclass + + + + + +A larger class of which a specific class is a member. +All members of a class are also members of the superclass. + + + + + +User + + + + + +A person interacting with a workstation. + + + + + +Widget + + + + + +An object providing a user-interface abstraction (for example, a Scrollbar +widget). + + + + + +Widget class + + + + + +The general group to which a specific widget belongs, +otherwise known as the type of the widget. + + + + + +Widget programmer + + + + + +A programmer who adds new widgets to the X Toolkit. + + + + + +Underlying Model + + + + + + +The underlying architectural model is based on the following premises: + + + + + + + + + +Every user-interface widget is associated with an X window. +The X window ID for a widget is readily available from the widget. +Standard Xlib calls can be used by widgets for many of their input and +output operations. + + + + + + + + + + +The data for every widget is private to the widget and its subclasses. +That is, the data is neither directly accessible +nor visible outside of the module implementing the widget. +All program interaction with the widget is performed by a set of operations +(methods) that are defined for the widget. + + + + + + + + + + +Widget semantics are clearly separated from widget layout geometry. +Widgets are concerned with implementing specific user-interface +semantics. They have little control over issues such as their size or +placement relative to other widget peers. Mechanisms are provided for +associating geometric managers with widgets and for widgets to make +suggestions about their own geometry. + + + + + + +Conventions Used in this Manual + + + + +All resources available to the widgets are listed with each widget. Many +of these are available to more than one widget class due to the object +oriented nature of the Intrinsics. The new resources for each widget are +listed in bold text, and the inherited resources are listed in plain text. + + + + +Global symbols are printed in bold and can be function names, +symbols defined in include files, or structure names. Arguments are +printed in italics. + + + + +Each function is introduced by a general discussion that distinguishes +it from other functions. The function declaration itself follows, and +each argument is specifically explained. General discussion of the +function, if any is required, follows the arguments. Where +applicable, the last paragraph of the explanation lists the return values +of the function. + + + + +To eliminate any ambiguity between those arguments that you pass and +those that a function returns to you, the explanations for all +arguments that you pass start with the word specifies or, in the +case of multiple arguments, the word specify. The explanations +for all arguments that are returned to you start with the word +returns or, in the case of multiple arguments, the word +return. The explanations for all arguments that you can pass +and are returned start with the words specifies and returns. + + + + +Any pointer to a structure that is used to return a value is +designated as such by the _return suffix as part of its name. +All other pointers passed to these functions are used for reading +only. A few arguments use pointers to structures that are used for +both input and output and are indicated by using the _in_out +suffix. + + + + + + + +Format of the Widget Reference Chapters + + + + +The majority of this document is a reference guide for the Athena +widget set. Chapters three through six give the programmer all +information necessary to use the widgets. The layout of the chapters +follows a specific pattern to allow the programmer to easily find the +desired information. + + + +The first few pages of every chapter give an overview of the widgets +in that section. Widgets are grouped into chapters by functionality. + + + + "Chapter + + + +Simple Widgets + + + + + + "Chapter + + + +Menus + + + + + + "Chapter + + + +Text Widgets + + + + + + "Chapter + + + +Composite and Constraint Widget + + + + + + + +Following the introduction will be a description of each widget in that +chapter. When no functional grouping is obvious the widgets are listed +in alphabetical order, such as in chapters three and six. + + + +The first section of each widget's description is a table that +contains general information about this widget class. Here is the +table for the Box widget, and an explanation of all the entries. + + + + +Application Header file <X11/Xaw/Box.h> +Class Header file <X11/Xaw/BoxP.h> +Class boxWidgetClass +Class Name Box +Superclass Composite + + + + + + Application Header File + + + + +This file must be included when an application uses this widget. +It usually contains the class definition, and some resource macros. +This is often called the ``public'' header file. + + + + + + + Class Header File + + + +This file will only be used by widget programmers. It will need to be +included by any widget that subclasses this widget. This is often +called the ``private'' header file. + + + + + + + Class + + + +This is the widget class of this widget. This global symbol is passed to +XtCreateWidget so that the Intrinsics will know which type of widget +to create. + + + + + + + Class Name + + + +This is the resource name of this class. This name can be used in +a resource file to match any widget of this class. + + + + + + + Superclass + + + +This is the superclass that this widget class is descended from. If +you understand how the superclass works it will allow you to more quickly +understand what this widget does, since much of its functionality may be +inherited from its superclass. + + + + + + + + +After this table follows a general description of the default behavior of +this widget, as seen by the user. In many cases this functionality +may be overridden by the application programmer, or by the user. + + + +The next section is a table showing the +name, class, type and default value of each resource that is available +to this widget. There is also a column containing notes describing +special restrictions placed upon individual resources. + + + + + + + + + A + + + +This resource may be automatically adjusted when another +resource is changed. + + + + + + C + + + +This resource is only settable at widget creation time, and may not +be modified with . + + + + + + D + + + +Do not modify this resource. While setting this resource will +work, it can cause unexpected behavior. When this symbol appears +there is another, preferred, interface provided by the X Toolkit. + + + + + + R + + + +This resource is READ-ONLY, and may not be modified. + + + + + + + +After the resource table is a detailed description of every resource +available to that widget. Many of these are redundant, but printing +them with each widget saves page flipping. The names of the resources +that are inherited are printed in plain text, while the names of the +resources that are new to this class are printed in bold. +If you have already read the description of the superclass you need +only pay attention to the resources printed in bold. + + + +For each composite widget there is a section on layout semantics that +follows the resource description. This section will describe the +effect of constraint resources on the layout of the children, as well +as a general description of where it prefers to place its children. + + + +Descriptions of default translations and action routines come next, for +widgets to which they apply. The last item in each widget's +documentation is the description of all convenience routines provided by +the widget. + + + +Input Focus + + + + + + + + +The Intrinsics define a resource on all Shell widgets that interact with +the window manager called input. This resource requests the +assistance of window manager in acquiring the input focus. The +resource defaults to False in the Intrinsics, but is redefined to +default to True when an application is using the Athena widget +set. An application programmer may override this default and set the +resource back to False if the application does not need the window +manager to give it the input focus. See the +X Toolkit Intrinsics - C Language Interface for details +on the input resource. + + + + diff --git a/specs/CH2.xml b/specs/CH2.xml new file mode 100644 index 0000000..98ac97e --- /dev/null +++ b/specs/CH2.xml @@ -0,0 +1,1892 @@ +Using Widgets + +Using Widgets + +Widgets serve as the primary tools for building a user interface or +application environment. The Athena widget set consists of primitive +widgets that contain no children (for example, a command button) and +composite widgets which may contain one or more widget children (for +example, a Box widget). + + +The remaining chapters explain the widgets that are provided +by the Athena widget set. +These user-interface components serve as an interface for +application programmers who do not want to implement their own widgets. +In addition, they serve as a starting point +for those widget programmers who, using the Intrinsics mechanisms, +want to implement alternative application programming interfaces. + + +This chapter is a brief introduction to widget programming. The +examples provided use the Athena widgets, though most of the concepts +will apply to all widget sets. Although there are several programming +interfaces to the X Toolkit, only one is described here. A full +description of the programming interface is provided in the document +X Toolkit Intrinsics - C Language Interface. + + +Setting the Locale + + + + + +If it is desirable that the application take advantage of +internationalization (i18n), you must establish locale with +XtSetLanguageProc +before XtDisplayInitialize or +is called. For full details, please refer to the document +X Toolkit Intrinsics - C Language Interface, section 2.2. However, the following simplest-case +call is sufficient in many or most applications. + + + + + + + + + + XtSetLanguageProc(NULL, NULL, NULL); + + + + +Most notably, this will affect the Standard C locale, determine which +resource files will be loaded, and what fonts will be required of FontSet +specifications. In many cases, the addition of this line is the only source change +required to internationalize Xaw programs, and will not disturb the function +of programs in the default "C" locale. + + + +Initializing the Toolkit + + + + + +You must call a toolkit initialization function before invoking any +other toolkit routines (besides locale setting, above). + +opens the X server connection, parses the command line, +and creates an initial widget that will serve as the root of +a tree of widgets created by this application. + + + + + + + Widget XtAppInitialize + XtAppContext app_context_return + String application_class + XrmOptionDescRec options + Cardinal num_options + int *argc_in_out + String *argv_in_out + String *fallback_resources + ArgList args + Cardinal num_args + + + + + + + app_con_return + + + +Returns the application context of this application, if non-NULL. + + + + + + application_class + + + +Specifies the class name of this application, +which is usually the generic name for all instances of this application. +A useful convention is to form the class name by capitalizing the +first letter of the application name. For example, the application named +``xman'' has a class name of ``Xman''. + + + + + + options + + + +Specifies how to parse the command line for any application-specific +resources. +The options argument is passed as a parameter to +XrmParseCommand. +For further information, +see Xlib - C Language Interface. + + + + + + num_options + + + +Specifies the number of entries in the options list. + + + + + + argc_in_out + + + +Specifies a pointer to the number of command line parameters. + + + + + + argv_in_out + + + +Specifies the command line parameters. + + + + + + fallback_resources + + + +Specifies resource values to be used if the site-wide application class +defaults file cannot be opened, or NULL. + + + + + + args + + + +Specifies the argument list to use when creating the Application shell. + + + + + + num_args + + + +Specifies the number of arguments in args. + + + + + + + +This function will remove the command line arguments that the toolkit +reads from argc_in_out, and argv_in_out. It will then +attempt to open the display. If the display cannot be opened, an error +message is issued and XtAppInitialize terminates the application. Once +the display is opened, all resources are read from the locations +specified by the Intrinsics. This function returns an ApplicationShell +widget to be used as the root of the application's widget tree. + + + +Creating a Widget + + + + + + + + +Creating a widget is a three-step process. First, the widget instance +is allocated, and various instance-specific attributes are set by +using XtCreateWidget. Second, the widget's parent is informed +of the new child by using XtManageChild. Finally, X windows are +created for the parent and all its children by using +and specifying the top-most widget. The first two steps can be +combined by using . In addition, + is automatically called when the child becomes +managed if the parent is already realized. + + + +To allocate, initialize, and manage a widget, use +XtCreateManagedWidget . + + + + Widget XtCreateManagedWidget + String name + WidgetClass widget_class + Widget parent + ArgList args + Cardinal num_args + + + + + + + name + + + +Specifies the instance name for the created widget that is used for retrieving +widget resources. + + + + + + widget_class + + + +Specifies the widget class pointer for the created widget. + + + + + + parent + + + +Specifies the parent widget ID. + + + + + + args + + + +Specifies the argument list. The argument list is a variable-length +list composed of name and value pairs that contain information +pertaining to the specific widget instance being created. For further +information, see Section 2.7.2. + + + + + + num_args + + + +Specifies the number of arguments in the argument list. +If the num_args is zero, the argument list is never referenced. + + + + + + + +When a widget instance is successfully created, the widget identifier +is returned to the application. If an error is encountered, the +XtError +routine is invoked to inform the user of the error. + + + + +For further information, see X Toolkit Intrinsics - C Language Interface. + + + +Common Resources + + + + + + +Although a widget can have unique arguments that it understands, all +widgets have common arguments that provide some regularity of operation. +The common arguments allow arbitrary widgets to be managed by +higher-level components without regard for the individual widget type. +Widgets will ignore any argument that they do not understand. + + + +The following resources are retrieved from the argument list +or from the resource database by all of the Athena widgets: + + + + + + + + + Name + Class + Type + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + True + + + background + Background + Pixel + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + 1 + + + colormap + Colormap + Colormap + Parent's Colormap + + + depth + Depth + int + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + NULL + + + height + Height + Dimension + widget dependent + + + mappedWhenManaged + MappedWhenManaged + Boolean + True + + + screen + Screen + Screen + Parent's Screen + + + sensitive + Sensitive + Boolean + True + + + translations + Translations + TranslationTable + widget dependent + + + width + Width + Dimension + widget dependent + + + x + Position + Position + 0 + + + y + Position + Position + 0 + + + + + + + + + +The following additional resources are retrieved from the argument list +or from the resource database by many of the Athena widgets: + + + + + + + + + Name + Class + Type + Default Value + + + + + callback + Callback + XtCallbackList + NULL + + + cursor + Cursor + Cursor + widget dependent + + + foreground + Foreground + Pixel + XtDefaultForeground + + + insensitiveBorder + Insensitive + Pixmap + GreyPixmap + + + + + + + + +Resource Conversions + + + + + + + + +Most resources in the Athena widget set have a converter registered that +will translate the string in a resource file to the correct internal +representation. While some are obvious (string to integer, for example), +others need specific mention of the allowable values. Three general +converters are described here: + + + + +Cursor + + + + +Pixel + + + + +Bitmap + + + + + +Many widgets have defined special converters that apply only to that +widget. When these occur, the documentation section for that widget +will describe the converter. + + +Cursor Conversion + + + + + +The value for the cursorName resource is specified in the resource +database as a string, and is of the following forms: + + + + +A standard X cursor name from < X11/cursorfont.h >. +The names in cursorfont.h each describe a specific cursor. The +resource names for these cursors are exactly like the names in this file +except the XC_ is not used. The cursor definition XC_gumby +has a resource name of gumby. + + + + +Glyphs, as in FONT font-name glyph-index [[ font-name ] glyph-index ]. +The first font and glyph specify the cursor source pixmap. +The second font and glyph specify the cursor mask pixmap. +The mask font defaults to the source font, +and the mask glyph index defaults to the source glyph index. + + + + +A relative or absolute file name. +If a relative or absolute file name is specified, that file is used to +create the source pixmap. Then the string "Mask" is appended to +locate the cursor mask pixmap. If the "Mask" file does not exist, the +suffix "msk" is tried. If "msk" fails, no cursor mask will be used. +If the filename does not start with '/' or './' the the bitmap +file path is used (see section 2.4.3). + + + + + +Pixel Conversion + + + + + + + +The string-to-pixel converter takes any name that is acceptable to +XParseColor (see Xlib - C Language Interface). In addition this routine understands +the special toolkit symbols `XtDefaultForeground' and +`XtDefaultBackground', described in X Toolkit Intrinsics - C Language Interface. In short the acceptable +pixel names are: + + + + +Any color name for the rgb.txt file (typically in the directory +/usr/lib/X11 on POSIX systems). + + + + +A numeric specification of the form #<red><green><blue> where these +numeric values are hexadecimal digits (both upper and lower case). + + + + +The special strings `XtDefaultForeground' and `XtDefaultBackground' + + + + + +Bitmap Conversion + + + + + + + +The string-to-bitmap converter attempts to locate a file containing +bitmap data whose name is specified by the input string. If the file +name is relative (i.e. does not begin with / or ./), the directories to +be searched are specified in the bitmapFilePath resource--class +BitmapFilePath. This resource specifies a colon (:) separated +list of directories that will be searched for the named bitmap or +cursor glyph (see section 2.4.1). The bitmapFilePath resource is +global to the application, and may not be specified differently +for each widget that wishes to convert a cursor to bitmap. In addition +to the directories specified in the bitmapFilePath resource a +default directory is searched. When using POSIX the default +directory is +/usr/include/X11/bitmaps . + + + + +Realizing a Widget + + + + + + +The + +function performs two tasks: + + + + +Calculates the geometry constraints of all managed descendants +of this widget. The actual calculation is put off until realize time +for performance reasons. + + + + +Creates an X window for the widget and, if it is a composite widget, +realizes each of its managed children. + + + + void XtRealizeWidget + Widget w + + + + + + + +Specifies the widget. + + + + + +For further information about this function, +see the X Toolkit Intrinsics - C Language Interface. + + + +Processing Events + + + + + + + +Now that the application has created, managed and realized its +widgets, it is ready to process the events that will be delivered by the +X Server to this client. A function call that will process the +events is . + + + + void XtAppMainLoop + XtAppContext app_context + + + + + + + app_context + + + +Specifies the application context of this application. The value is +normally returned by . + + + + + + + +This function never returns: it is an infinite loop that processes the +X events. User input can be handled through callback procedures and +application defined action routines. More details are provided in +X Toolkit Intrinsics - C Language Interface. + + + +Standard Widget Manipulation Functions + + + + + +After a widget has been created, a client can interact with that +widget by calling one of the standard widget manipulation routines +provided by the Intrinsics, or a widget class-specific manipulation routine. + + + +The Intrinsics provide generic routines to give the application programmer +access to a set of standard widget functions. The common widget +routines let an application or composite widget perform the following +operations on widgets without requiring explicit knowledge of the widget +type. + + + + +Control the mapping of widget windows + + + + +Destroy a widget instance + + + + +Obtain an argument value + + + + +Set an argument value + + + + +Mapping Widgets + + +By default, +widget windows are mapped (made viewable) automatically by +. This behavior can be disabled by using +, making the client responsible for calling + to make the widget viewable. + + + + + + void XtSetMappedWhenManaged + Widget w + Boolean map_when_managed + + + + + + + w + + + +Specifies the widget. + + + + + + map_when_managed + + + +Specifies the new value. +If map_when_managed is True, the widget is mapped automatically +when it is realized. If map_when_managed is False, the client +must call + +or make a second call to + +to cause the child window to be mapped. + + + + + + + + +The definition for + +is: + + + + void XtMapWidget + Widget w + + + + + + + w + + + +Specifies the widget. + + + + + + + +When you are creating several children in sequence for a previously +realized common parent it is generally more efficient to construct a +list of children as they are created (using XtCreateWidget) and +then use to request that their parent managed +them all at once. By managing a list of children at one time, the +parent can avoid wasteful duplication of geometry processing and the +associated ``screen flash''. + + + + + void XtManageChildren + WidgetList children + Cardinal num_children + + + + + + + children + + + +Specifies a list of children to add. + + + + + + num_children + + + +Specifies the number of children to add. + + + + + + + +If the parent is already visible on the screen, it is especially +important to batch updates so that the minimum amount of visible window +reconfiguration is performed. + + + +For further information about these functions, +see the X Toolkit Intrinsics - C Language Interface. + + + +Destroying Widgets + + +To destroy a widget instance of any type, use + + + + + void XtDestroyWidget + Widget w + + + + + + + w + + + +Specifies the widget. + + + + + + + + +destroys the widget and recursively destroys any children that it may have, +including the windows created by its children. +After calling +XtDestroyWidget , +no further references should be made to the widget or any children +that the destroyed widget may have had. + + + +Retrieving Widget Resource Values + + +To retrieve the current value of a resource attribute associated +with a widget instance, use +XtGetValues . + + + + void XtGetValues + Widget w + ArgList args + Cardinal num_args + + + + + + + w + + + +Specifies the widget. + + + + + + args + + + +Specifies a variable-length argument list of name and address +pairs that contain the resource name and the address into which the +resource value is stored. + + + + + + num_args + + + +Specifies the number of arguments in the argument list. + + + + + + + +The arguments and values passed in the argument list are dependent on +the widget. Note that the caller is responsible for providing space +into which the returned resource value is copied; the ArgList +contains a pointer to this storage (e.g. x and y must be +allocated as Position). For further information, see the X Toolkit Intrinsics - C Language Interface. + + + +Modifying Widget Resource Values + + +To modify the current value of a resource attribute associated with a +widget instance, use +XtSetValues . + + + + void XtSetValues + Widget w + ArgList args + Cardinal num_args + + + + + + + w + + + +Specifies the widget. + + + + + + args + + + +Specifies an array of name and value pairs that contain the +arguments to be modified and their new values. + + + + + + num_args + + + +Specifies the number of arguments in the argument list. + + + + + + + +The arguments and values that are passed will depend on the widget +being modified. Some widgets may not allow certain resources to be +modified after the widget instance has been created or realized. +No notification is given if any part of a request is +ignored. + + + +For further information about these functions, see the X Toolkit Intrinsics - C Language Interface. + + + +The argument list entry for + +specifies the address to which the caller wants the value copied. The +argument list entry for +XtSetValues , +however, contains the new value itself, if the size of value is less than +sizeof(XtArgVal) (architecture dependent, but at least sizeof(long)); +otherwise, it is a pointer to the value. String resources are always +passed as pointers, regardless of the length of the string. + + + + + +Using the Client Callback Interface + + + + + + +Widgets can communicate changes in their state to their clients +by means of a callback facility. +The format for a client's callback handler is: + + + + void CallbackProc + Widget w + XtPointer client_data + XtPointer call_data + + + + + + + w + + + +Specifies widget for which the callback is registered. + + + + + + client_data + + + +Specifies arbitrary client-supplied data that the widget should pass +back to the client when the widget executes the client's callback +procedure. This is a way for the client registering the callback to +also register client-specific data: a pointer to additional information +about the widget, a reason for invoking the callback, and so on. If no +additional information is necessary, NULL may be passed as this argument. +This field is also frequently known as the closure. + + + + + + call_data + + + +Specifies any callback-specific data the widget wants to pass to the client. +For example, when Scrollbar executes its jumpProc callback list, +it passes the current position of the thumb in call_data. + + + + + + + +Callbacks can be registered either by creating an argument containing +the callback list described below or by using the special convenience +routines and XtAddCallbacks. When the widget +is created, a pointer to a list of callback procedure and data pairs can +be passed in the argument list to +XtCreateWidget . +The list is of type +XtCallbackList : + + + + + + + + + + + +typedef struct { + XtCallbackProc callback; + XtPointer closure; +} XtCallbackRec, *XtCallbackList; + + + + +The callback list must be allocated and initialized before calling +XtCreateWidget . + +The end of the list is identified by an entry containing NULL in +callback and closure. Once the widget is created, the client can change +or de-allocate this list; the widget itself makes no further reference +to it. The closure field contains the client_data passed to the +callback when the callback list is executed. + + + +The second method for registering callbacks is to use + +after the widget has been created. + + + + void XtAddCallback + Widget w + String callback_name + XtCallbackProc callback + XtPointer client_data + + + + + + + w + + + +Specifies the widget to add the callback to. + + + + + + callback_name + + + +Specifies the callback list within the widget to append to. + + + + + + callback + + + +Specifies the callback procedure to add. + + + + + + client_data + + + +Specifies the data to be passed to the callback when it is invoked. + + + + + + + + +adds the specified callback to the list for the named widget. + + + +All widgets provide a callback list named +destroyCallback + +where clients can register procedures that are to be executed when the +widget is destroyed. The destroy callbacks are executed when the widget +or an ancestor is destroyed. The call_data argument is unused for +destroy callbacks. + + + +Programming Considerations + + + + + +This section provides some guidelines on how to set up an application +program that uses the X Toolkit. + + +Writing Applications + + + + + +When writing an application that uses the X Toolkit, +you should make sure that your application performs the following: + + + + +Include +< X11/Intrinsic.h > +in your application programs. +This header file automatically includes +< X11/Xlib.h >, +so all Xlib functions also are defined. +It may also be necessary to include < X11/StringDefs.h > when setting +up argument lists, as many of the XtNsomething definitions are +only defined in this file. + + + + +Include the widget-specific header files for each widget type +that you need to use. +For example, +< X11/Xaw/Label.h > +and +< X11/Xaw/Command.h >. + + + + +Call the + + +function before invoking any other toolkit or Xlib functions. +For further information, +see Section 2.1 and the X Toolkit Intrinsics - C Language Interface. + + + + +To pass attributes to the widget creation routines that will override +any site or user customizations, set up argument lists. In this +document, a list of valid argument names is provided in the discussion +of each widget. The names each have a global symbol defined that begins +with XtN to help catch spelling errors. For example, +XtNlabel is defined for the label resource of many widgets. + + + + + +For further information, see Section 2.9.2.2. + + + + +When the argument list is set up, create the widget with the + function. For further information, see +Section 2.2 and the X Toolkit Intrinsics - C Language Interface. + + + + + +If the widget has any callback routines, set by the +XtNcallback +argument or the + +function, declare these routines within the application. + + + + + +After creating the initial widget hierarchy, windows must be created +for each widget by calling + +on the top level widget. + + + + + +Most applications now sit in a loop processing events using +XtAppMainLoop , +for example: + + + + + + +XtCreateManagedWidget(name, class, parent, args, num_args); +XtRealizeWidget(shell); +XtAppMainLoop(app_context); + + + + + +For information about this function, see the X Toolkit Intrinsics - C Language Interface. + + + + +Link your application with +libXaw +(the Athena widgets), +libXmu +(miscellaneous utilities), +libXt +(the X Toolkit Intrinsics), +libSM +(Session Management), +libICE +(Inter-Client Exchange), +libXext +(the extension library needed for the shape extension code which allows +rounded Command buttons), and +libX11 +(the core X library). +The following provides a sample command line: + + + + + + + + + + + + + + +cc -o application application.c \-lXaw \-lXmu \-lXt \ +\-lSM \-lICE \-lXext \-lX11 + + + + + + +Changing Resource Values + + + +The Intrinsics support two methods of changing the default resource +values; the resource manager, and an argument list passed into +XtCreateWidget. While resources values will get updated no matter +which method you use, the two methods provide slightly different +functionality. + + + Resource Manager + + +This method picks up resource definitions described in Xlib - C Language Interface from +many different locations at run time. The locations most important to +the application programmer are the fallback resources and the +app-defaults file, (see X Toolkit Intrinsics - C Language Interface for the complete list). +Since these resource are loaded at run time, they can be overridden by +the user, allowing an application to be customized to fit the +particular needs of each individual user. These values can also be +modified without the need to rebuild the application, allowing rapid +prototyping of user interfaces. Application programmers should use +resources in preference to hard-coded values whenever possible. + + + + + Argument Lists + + +The values passed into the widget at creation time via an argument list +cannot be modified by the user, and allow no opportunity for +customization. It is used to set resources that cannot be specified as +strings (e.g. callback lists) or resources that should not be +overridden (e.g. window depth) by the user. + + + + + + +Specifying Resources + + +It is important for all X Toolkit application programmers to +understand how to use the X Resource Manager to specify resources for +widgets in an X application. This section will describe the most common +methods used to specify these resources, and how to use the X Resource +manager. + + + + + Xrdb + + + +The xrdb utility may be used to load a file containing +resources into the X server. Once the resources are loaded, the +resources will affect any new applications started on the display that +they were loaded onto. + + + + + + + + Application Defaults + + +The application defaults (app-defaults) file (normally in +/usr/lib/X11/app-defaults/classname) for an application is loaded +whenever the application is started. + + + + + + + +The resource specification has two colon-separated parts, a name, and +a value. The value is a string whose format is dependent on the +resource specified by name. Name is constructed by +appending a resource name to a full widget name. + + + +The full widget name is a list of the name of every ancestor of the +desired widget separated by periods (.). Each widget also has a class +associated with it. A class is a type of widget (e.g. Label or +Scrollbar or Box). Notice that class names, by convention, begin with +capital letters and instance names begin with lower case letters. The +class of any widget may be used in place of its name in a resource +specification. Here are a few examples: + + + + xman.form.button1 + + + +This is a fully specified resource name, and will affect only widgets +called button1 that are children of widgets called form that are +children of +applications named xman. (Note that while typically two widgets that +are siblings will have different names, it is not prohibited.) + + + + + + + Xman.Form.Command + + + +This will match any Command widget that is a child of a Form widget +that is itself a child of an application of class Xman. + + + + + + Xman.Form.button1 + + + +This is a mixed resource name with both widget names and classes specified. + + + + + + + +This syntax allows an application programmer to specify any widget +in the widget tree. To match more than one widget (for example a user +may want to make all Command buttons blue), use an asterisk (*) +instead of a period. When an asterisk is used, any number of widgets +(including zero) may exist between the two widget names. For example: + + + + Xman*Command + + + +This matches all Command widgets in the Xman application. + + + + + + Foo*button1 + + + +This matches any widget in the Foo application that is named button1. + + + + + + + +The root of all application widget trees is the widget returned by +. Even though this is actually an +ApplicationShell widget, the toolkit replaces its widget class with the +class name of the application. The name of this widget is either +the name used to invoke the application (argv[0]) or the name of +the application specified using the standard -name command line +option supported by the Intrinsics. + + + +The last step in constructing the resource name is to append the name of +the resource with either a period or asterisk to the full or partial +widget name already constructed. + + + + *foreground:Blue + + + +Specifies that all widgets in all applications will have a foreground +color of blue. + + + + + + Xman*borderWidth:10 + + + +Specifies that all widgets in an application whose class is Xman will +have a border width of 10 (pixels). + + + + + + xman.form.button1.label:Testing + + + +Specifies that a particular widget in the xman application will have a +label named Testing. + + + + + + + +An exclamation point (!) in the first column of a line indicates +that the rest of the line should be treated as a comment. + + + +Final Words + + + +The Resource manager is a powerful tool that can be used very +effectively to customize X Toolkit applications at run time by either the +application programmer or the user. Some final points to note: + + + + +An application programmer may add new resources to their +application. These resources are associated with the global +application, and not any particular widget. The X Toolkit function used for +adding the application resources is XtGetApplicationResources. + + + + + +Be careful when creating resource files. Since widgets will +ignore resources that they do not understand, any spelling +errors will cause a resource to have no effect. + + + + +Only one resource line will match any given resource. There is a set +of precedence rules, which take the following general stance. + + + + + + + +More specific overrides less specific, thus period always overrides asterisk. + + + + +Names on the left are more specific and override names on the right. + + + + +When resource specifications are exactly the same, user defaults +will override program defaults. + + + + + + + +For a complete explanation of the rules of precedence, and +other specific topics see X Toolkit Intrinsics - C Language Interface and Xlib - C Language Interface. + + + +Creating Argument Lists + + + +To set up an argument list for the inline specification of widget attributes, +you may use any of the four approaches discussed in this section. +Each resource name has a global symbol associated with it. This +global symbol has the form XtNresource name. For example, the +symbol for ``foreground'' is XtNforeground. For further information, +see the X Toolkit Intrinsics - C Language Interface. + + + +Argument are specified by using the following structure: + + + + + + + + +typedef struct { + String name; + XtArgVal value; +} Arg, *ArgList; + + + + +The first approach is to statically initialize the argument list. +For example: + + + + + + +static Arg arglist[] = { + {XtNwidth, (XtArgVal) 400}, + {XtNheight, (XtArgVal) 300}, +}; + + + + +This approach is convenient for lists that do not need to be computed +at runtime and makes adding or deleting new elements easy. +The + +XtNumber +macro is used to compute the number of elements in the argument list, +preventing simple programming errors: + + + + +XtCreateWidget(name, class, parent, arglist, XtNumber(arglist)); + + + + + +The second approach is to use the +XtSetArg +macro. +For example: + + + + + + +Arg arglist[10]; +XtSetArg(arglist[1], XtNwidth, 400); +XtSetArg(arglist[2], XtNheight, 300); + + + + +To make it easier to insert and delete entries, +you also can use a variable index: + + + + + + +Arg arglist[10]; +Cardinal i=0; +XtSetArg(arglist[i], XtNwidth, 400); i++; +XtSetArg(arglist[i], XtNheight, 300); i++; + + + + +The i variable can then be used as the argument list count in the widget +create function. +In this example, + +XtNumber +would return 10, not 2, and therefore is not useful. + +You should not use auto-increment or auto-decrement +within the first argument to +XtSetArg . +As it is currently implemented, +XtSetArg +is a macro that dereferences the first argument twice. + + + + +The third approach is to individually set the elements of the +argument list array: + + + + + + +Arg arglist[10]; +arglist[0].name = XtNwidth; +arglist[0].value = (XtArgVal) 400; +arglist[1].name = XtNheight; +arglist[1].value = (XtArgVal) 300; + + + + +Note that in this example, as in the previous example, + +XtNumber +would return 10, not 2, and therefore would not be useful. + + + +The fourth approach is to use a mixture of the first and third approaches: +you can statically define the argument list but modify some entries at runtime. +For example: + + + + + + +static Arg arglist[] = { + {XtNwidth, (XtArgVal) 400}, + {XtNheight, (XtArgVal) NULL}, +}; +arglist[1].value = (XtArgVal) 300; + + + + +In this example, + +XtNumber +can be used, as in the first approach, for easier code maintenance. + + + + + +Example Programs + + + + + + +The best way to understand how to use any programming library is by +trying some simple examples. A collection of example programs that +introduces each of the widgets in that Athena widget set, as well as many +important toolkit programming concepts, is available in the X11R5 contrib +release as distributed by the X Consortium. It can be found in the +directory contrib/examples/Xaw in the archive +at +See the README file from that directory for a guide +to the examples. + + + + diff --git a/specs/CH3.xml b/specs/CH3.xml new file mode 100644 index 0000000..37ee8b5 --- /dev/null +++ b/specs/CH3.xml @@ -0,0 +1,123 @@ + +Simple Widgets + + + +Each of these widgets performs a specific user interface function. They +are simple because they cannot have widget children\(emthey may only +be used as leaves of the widget tree. These widgets display information or +take user input. + + + + + Command + + +A push button that, when selected, may cause a specific action +to take place. This widget can display a multi-line string or a bitmap or pixmap image. + + + + + Grip + + +A rectangle that, when selected, will cause an action to take place. + + + + + Label + + +A rectangle that can display a multi-line string or a bitmap or pixmap image. + + + + + + List + + +A list of text strings presented in row column format that may be +individually selected. When an element is selected an action may take +place. + + + + + + Panner + + +A rectangular area containing a slider that may be moved in two +dimensions. Notification of movement may be continuous or discrete. + + + + + + Repeater + + +A push button that triggers an action at an increasing rate when selected. +This widget can display a multi-line string or a bitmap or pixmap image. + + + + + + Scrollbar + + +A rectangular area containing a thumb that when slid along one +dimension may cause a specific action to take place. The Scrollbar may +be oriented horizontally or vertically. + + + + + + Simple + + +The base class for most of the simple widgets. Provides a rectangular +area with a settable mouse cursor and special border. + + + + + + StripChart + + +A real time data graph that will automatically update and scroll. + + + + + + Toggle + + +A push button that contains state information. Toggles +may also be used as "radio buttons" to implement a "one of many" or +"zero or one of many" group +of buttons. This widget can display a multi-line string or a bitmap or pixmap image. + + + + + + + + + + + + + + + + diff --git a/specs/CH4.xml b/specs/CH4.xml new file mode 100644 index 0000000..0546af5 --- /dev/null +++ b/specs/CH4.xml @@ -0,0 +1,102 @@ + +Menus + +The Athena widget set provides support for single paned non-hierarchical +popup and pulldown menus. Since menus are such a common user interface +tool, support for them must be provided in even the most basic widget +sets. In menuing as in other areas, the Athena Widget Set provides only +basic functionality. + + +Menus in the Athena widget set are implemented as a menu container (the +SimpleMenu widget) and a collection of objects that comprise the +menu entries. The SimpleMenu widget is itself a direct subclass of the +OverrideShell widget class, so no other shell is necessary when +creating a menu. The managed children of a SimpleMenu must be +subclasses of the Sme (Simple Menu Entry) object. + + +The Athena widget set provides three classes of Sme objects that may be +used to build menus. + + + + + Sme + + +The base class of all menu entries. It may be used as a menu entry +itself to provide blank space in a menu. "Sme" means "Simple Menu +Entry." + + + + + SmeBSB + + +This menu entry provides a selectable entry containing a text string. +A bitmap may also be placed in the left and right margins. "BSB" means +"Bitmap String Bitmap." + + + + + SmeLine + + +This menu entry provides an unselectable entry containing a separator line. + + + + + + +The SimpleMenu widget informs the window manager that it should ignore +its window by setting the Override Redirect flag. This is the +correct behavior for the press-drag-release style of menu operation. If +click-move-click or "pinable" menus are desired it is the +responsibility of the application programmer, using the SimpleMenu +resources, to inform the window manager of the menu. + + +To allow easy creation of pulldown menus, a MenuButton widget is +also provided as part of the Athena widget set. + + +Using the Menus + + + + + + +The default configuration for the menus is press-drag-release. +The menus will typically be +activated by clicking a pointer button while the pointer is over a +MenuButton, causing the menu to appear in a fixed location relative to +that button; this is a pulldown menu. Menus may also be activated + +when a specific pointer and/or key sequence is used anywhere in the +application; this is a popup menu (e.g. clicking Ctrl-<pointer + +button 1> in the common application xterm). In this +case the menu should be positioned under +the cursor. Typically menus will be placed so the pointer cursor is on +the first menu entry, or the last entry selected by the user. + + + +The menu remains on the screen as long as the pointer button is held +down. Moving the pointer will highlight different menu items. +If the pointer leaves the menu, or moves over an entry that cannot +be selected then no menu entry will highlighted. When the desired menu +entry has been highlighted, releasing the pointer button removes the menu, +and causes any mechanism associated with this entry to be invoked. + + + + + + + diff --git a/specs/CH5.xml b/specs/CH5.xml new file mode 100644 index 0000000..2636aff --- /dev/null +++ b/specs/CH5.xml @@ -0,0 +1,397 @@ + +Text Widgets + + +The Text widget provides a window that will allow an application +to display and edit one or more lines of text. Options are provided to +allow the user to add Scrollbars to its window, search for a specific +string, and modify the text in the buffer. + + +The Text widget is made up of a number of pieces; it was modularized to +ease customization. The AsciiText widget class (actually not limited to +ASCII but so named for compatibility) is be general enough to most +needs. If more flexibility, special features, or extra functionality is +needed, they can be added by implementing a new TextSource or TextSink, or +by subclassing the Text Widget (See Section 5.8 for customization +details.) + + +The words insertion point are used in this chapter to refer to the text +caret. This is the symbol that is displayed between two characters in +the file. The insertion point marks the location where any new characters +will be added to the file. To avoid confusion the pointer cursor will +always be referred to as the pointer. + + +The text widget supports three edit modes, controlling the types of +modifications a user is allowed to make: + + + + Append-only + Editable + Read-only + + + +Read-only mode does not allow the user or the programmer to modify the text +in the widget. While the entire string may be reset in +read-only mode with , it cannot be modified via +with . Append-only and editable modes allow +the text at the insertion point to be modified. The only difference is +that text may only be added to or removed from the end of a buffer in +append-only mode. + + +Text Widget for Users + + + + + + +The Text widget provides many of the common keyboard editing commands. +These commands allow users to move around and edit the buffer. If an +illegal operation is attempted, (such as deleting characters in a +read-only text widget), the X server will beep. + + +Default Key Bindings + + + +The default key bindings are patterned after those in the EMACS text editor: + + + + +Ctrl-a Beginning Of Line Meta-b Backward Word +Ctrl-b Backward Character Meta-f Forward Word +Ctrl-d Delete Next Character Meta-i Insert File +Ctrl-e End Of Line Meta-k Kill To End Of Paragraph +Ctrl-f Forward Character Meta-q Form Paragraph +Ctrl-g Multiply Reset Meta-v Previous Page +Ctrl-h Delete Previous Character Meta-y Insert Current Selection +Ctrl-j Newline And Indent Meta-z Scroll One Line Down +Ctrl-k Kill To End Of Line Meta-d Delete Next Word +Ctrl-l Redraw Display Meta-D Kill Word +Ctrl-m Newline Meta-h Delete Previous Word +Ctrl-n Next Line Meta-H Backward Kill Word +Ctrl-o Newline And Backup Meta-< Beginning Of File +Ctrl-p Previous Line Meta-> End Of File +Ctrl-r Search/Replace Backward Meta-] Forward Paragraph +Ctrl-s Search/Replace Forward Meta-[ Backward Paragraph +Ctrl-t Transpose Characters +Ctrl-u Multiply by 4 Meta-Delete Delete Previous Word +Ctrl-v Next Page Meta-Shift Delete Kill Previous Word +Ctrl-w Kill Selection Meta-Backspace Delete Previous Word +Ctrl-y Unkill Meta-Shift Backspace Kill Previous Word +Ctrl-z Scroll One Line Up +Ctrl-\\ Reconnect to input method +Kanji Reconnect to input method + + + + + +In addition, the pointer may be used to cut and paste text: + + + + + + + Button 1 Down Start Selection + Button 1 Motion Adjust Selection + Button 1 Up End Selection (cut) + + Button 2 Down Insert Current Selection (paste) + + Button 3 Down Extend Current Selection + Button 3 Motion Adjust Selection + Button 3 Up End Selection (cut) + + + + + +Since all of these key and pointer bindings are set through the +translations and resource manager, the user and the application +programmer can modify them by changing the Text widget's +translations resource. + + + + +Search and Replace + + + + +The Text widget provides a search popup that can be used to search for a +string within the current Text widget. The popup can be activated by +typing either Control-r or Control-s. If Control-s is +used the search will be forward in the file from the current location of the +insertion point; if Control-r is used the search will be backward. The +activated popup is placed under the pointer. It has a number of buttons +that allow both text searches and text replacements to be performed. + + + +At the top of the search popup are two toggle buttons labeled +backward and forward. One of these buttons will always be +highlighted; this is the direction in which the search will be +performed. The user can change the direction at any time by clicking on +the appropriate button. + + + +Directly under the buttons there are two text areas, one labeled +Search for: and the other labeled Replace with:. If this is +a read-only Text widget the Replace with: field will be insensitive +and no replacements will be allowed. After each of these labels will be +a text field. This field will allow the user to enter a string to +search for and the string to replace it with. Only one of these text +fields will have a window border around it; this is the active text +field. Any key presses that occur when the focus in in the search popup +will be directed to the active text field. There are also a few special +key sequences: + + + +Carriage Return: Execute the action, and pop down the search widget. +Tab: Execute the action, then move to the next field. +Shift Carriage Return: Execute the action, then move to the next field. +Control-q Tab: Enter a Tab into a text field. +Control-c: Pop down the search popup. + + + + +Using these special key sequences should allow simple +searches without ever removing one's hands from the keyboard. + + + +Near the bottom of the search popup is a row of buttons. These buttons +allow the same actions to to be performed as the key sequences, but the +buttons will leave the popup active. This can be quite useful if many +searches are being performed, as the popup will be left on the display. +Since the search popup is a transient window, it may be picked +up with the window manager and pulled off to the side for use +at a later time. + + + + Search + + +Search for the specified string. + + + + + Replace + + +Replace the currently highlighted string with the string in the +Replace with text field, and move onto the next occurrence of the +Search for text field. The functionality is commonly referred to as +query-replace. + + + + + ReplaceAll + + +Replace all occurrences of the search string with the replace string from +the current insertion point position to the end (or beginning) of the +file. There is no key sequence to perform this action. + + + + + ReplaceAll + + +Remove the search popup from the screen. + + + + + + +Finally, when international resource is true, there may be a +pre-edit buffer below the button row, for composing input. Its presence +is determined by the X locale in use and the VendorShell's preeditType +resource. + + + +The widget hierarchy for the search popup is show below, all widgets +are listed by class and instance name. + + + + +Text <name of Text widget> + TransientShell search + Form form + Label label1 + Label label2 + Toggle backwards + Toggle forwards + Label searchLabel + Text searchText + Label replaceLabel + Text replaceText + Command search + Command replaceOne + Command replaceAll + Command cancel + + + + + +File Insertion + + + +To insert a file into a text widget, type the key sequence Meta-i, +which will activate the file insert popup. This popup will appear under +the pointer, and any text typed while the focus is in this popup will be +redirected to the text field used for the filename. When the desired +filename has been entered, click on Insert File, or type +Carriage Return. The named file will then be inserted in the text +widget beginning at the insertion point position. If an error occurs when +opening the file, an error message will be printed, prompting the user +to enter the filename again. The file insert may be aborted by clicking +on Cancel. If Meta-i is typed at a text widget that is +read-only, it will beep, as no file insertion is allowed. + + + +The widget hierarchy for the file insert popup is show below; all widgets +are listed by class and instance name. + + + + +Text <name of Text widget> + TransientShell insertFile + Form form + Label label + Text text + Command insert + Command cancel + + + + + +Text Selections for Users + + + +The text widgets have a text selection mechanism that allows +the user to copy pieces of the text into the PRIMARY selection, +and paste +into the text widget some text that another application (or text +widget) has put in the PRIMARY selection. + + + +One method of selecting text is to press pointer button 1 +on the beginning of the text to be selected, drag the pointer until all +of the desired text is highlighted, and then release the button to +activate the selection. Another method is to click pointer button 1 at +one end of the text to be selected, then click pointer button 3 at the +other end. + + + +To modify a currently active selection, press pointer button 3 near +either the end of the selection that you want to +adjust. This end of the selection may be moved while holding down pointer +button 3. When the proper area has been highlighted release the pointer +button to activate the selection. + + + +The selected text may now be pasted into another application, and +will remain active until some other client makes a selection. +To paste text that some other application has +put into the PRIMARY selection use pointer button 2. +First place the insertion point where you would like the text to be inserted, +then click and release pointer button 2. + + + +Rapidly clicking pointer button 1 the following number of times will adjust +the selection as described. + + + + Two + + + +Select the word under the pointer. A word boundary is defined by the +Text widget to be a Space, Tab, or Carriage Return. + + + + + + Three + + + +Select the line under the pointer. + + + + + + Four + + + +Select the paragraph under the pointer. A paragraph boundary is +defined by the text widget as two Carriage Returns in a row with only +Spaces or Tabs between them. + + + + + + Five + + + +Select the entire text buffer. + + + + + + +To unset the text selection, click pointer button 1 without moving it. + + + + + + + + + + + + + + + diff --git a/specs/CH6.xml b/specs/CH6.xml new file mode 100644 index 0000000..8424387 --- /dev/null +++ b/specs/CH6.xml @@ -0,0 +1,117 @@ + +Composite and Constraint Widgets + +These widgets may contain arbitrary widget children. They implement a +policy for the size and location of their children. + + + + + Box + + +This widget will pack its children as tightly as possible in non-overlapping rows. + + + + + Dialog + + +An implementation of a commonly used interaction semantic to prompt for +auxiliary input from the user, such as a filename. + + + + + Form + + +A more sophisticated layout widget that allows the children to specify +their positions relative to the other children, or to the edges of the Form. + + + + + Paned + + +Allows children to be tiled vertically or horizontally. Controls are +also provided to allow the user to dynamically resize the individual panes. + + + + + Porthole + + +Allows viewing of a managed child which is as large as, or larger than its +parent, typically under control of a Panner widget. + + + + + Tree + + +Provides geometry management of widgets arranged in a directed, acyclic graph. + + + + + Viewport + + +Consists of a frame, one or two scrollbars, and an inner window. The +inner window can contain all the data that is to be displayed. This inner +window will be clipped by the frame with the scrollbars controlling +which section of the inner window is currently visible. + + + + + + + + +The geometry management semantics provided by the X Toolkit give full +control of the size and position of a widget to the parent of that +widget. While the children are allowed to request a certain size or +location, it is the parent who makes the final decision. Many of the +composite widgets here will deny any geometry request from their +children by default. If a child widget is not getting the expected size +or location, it is most likely the parent disallowing a request, or +implementing semantics slightly different than those expected by the +application programmer. + + + +If the application wishes to change the size or location of +any widget it should make a call to . This will + +allow the widget to ask its parent for the new size or location. +As noted above the parent is allowed to refuse this request, +and the child must live with the result. If the +application is unable to achieve the desired semantics, then perhaps it +should use a different composite widget. Under no circumstances +should an application programmer resort to XtMoveWidget or + +XtResizeWidget; these functions are exclusively for the use of + +Composite widget implementors. + + + +For more information on geometry management consult the X Toolkit Intrinsics - C Language Interface. + + + + + + + + + + + + diff --git a/specs/CH7.xml b/specs/CH7.xml new file mode 100644 index 0000000..a84e3cf --- /dev/null +++ b/specs/CH7.xml @@ -0,0 +1,167 @@ + +Creating New Widgets (Subclassing) + +Although the task of creating a new widget may at first appear a little +daunting, there is a basic simple pattern that all widgets follow. The +Athena Widget library contains a special widget called the +Template widget that is intended to assist +the novice widget programmer in writing a custom widget. + + +Reasons for wishing to write a custom widget include: + + + + +Providing a graphical interface not currently supported by any existing +widget set. + + + + +Convenient access to resource management procedures to obtain fonts, +colors, etc., even if user customization is not desired. + + + + +Convenient access to user input dispatch and translation management procedures. + + + + +Access to callback mechanism for building higher-level application libraries. + + + + +Customizing the interface or behavior of an existing widget to suit a +special application need. + + + + +Desire to allow user customization of resources such as fonts, colors, +etc., or to allow convenient re-binding of keys and buttons to internal +functions. + + + + +Converting a non-Toolkit application to use the Toolkit. + + + + + +In each of these cases, the operation needed to create a new widget is +to "subclass" an existing one. If the desired semantics of the new +widget are similar to an existing one, then the implementation of the +existing widget should be examined to see how much work would be +required to create a subclass that will then be +able to share the existing class methods. Much time will be saved in +writing the new widget if an existing widget class Expose, Resize and/or +GeometryManager method can be used by the subclass. + + +Note that some trivial uses of a ``bare-bones'' widget may be achieved by +simply creating an instance of the Core +widget. The class variable to use when creating a Core widget is +widgetClass. +The geometry of the Core widget is determined entirely by the parent +widget. + + +It is very often the case than an application will have a special need +for a certain set of functions and that many copies of these functions +will be needed. For example, when converting an older application to use +the Toolkit, it may be desirable to have a "Window Widget" class that +might have the following semantics: + + + + +Allocate 2 drawing colors in addition to a background color. + + + + +Allocate a text font. + + + + +Execute an application-supplied function to handle exposure events. + + + + +Execute an application-supplied function to handle user input events. + + + + +It is obvious that a completely general-purpose WindowWidgetClass could +be constructed that would export all class methods as callbacks lists, +but such a widget would be very large and would have to choose some +arbitrary number of resources such as colors to allocate. An application +that used many instances of the general-purpose widget would therefore +un-necessarily waste many resources. + + +In this section, an outline will be given of the procedure to follow to +construct a special-purpose widget to address the items listed above. +The reader should refer to the appropriate sections of the +X Toolkit Intrinsics - C Language Interface +for complete details of the material outlined here. Section 1.4 of +the Intrinsics should be read in +conjunction with this section. + + +All Athena widgets have three separate files associated with them: + + + + +A "public" header file containing declarations needed by applications programmers + + + + +A "private" header file containing additional declarations needed by the +widget and any subclasses + + + + +A source code file containing the implementation of the widget + + + + + +This separation of functions into three files is suggested for all +widgets, but nothing in the Toolkit actually requires this format. In +particular, a private widget created for a single application may easily +combine the "public" and "private" header files into a single file, or +merge the contents into another application header file. Similarly, the +widget implementation can be merged into other application code. + + + +In the following example, the public header file +< X11/Xaw/Template.h >, +the private header file +< X11/Xaw/TemplateP.h > +and the source code file +< X11/Xaw/Template.c > +will be modified to produce the "WindowWidget" described above. +In each case, the files have been designed so that a global string +replacement of "Template" and "template" +with the name of your new widget, using +the appropriate case, can be done. + + + + + diff --git a/specs/Command.xml b/specs/Command.xml new file mode 100644 index 0000000..92d1b72 --- /dev/null +++ b/specs/Command.xml @@ -0,0 +1,525 @@ + +Command Widget + + + + + + + + +Application header file <X11/Xaw/Command.h> + +Class header file <X11/Xaw/CommandP.h> + +Class commandWidgetClass + +Class Name Command + +Superclass Label + + + + +The Command widget is an area, often rectangular, that contains text +or a graphical image. Command widgets are often referred to as +``push buttons.'' When the pointer is over a Command widget, the +widget becomes highlighted by drawing a rectangle around its perimeter. +This highlighting indicates that the widget is ready for selection. +When mouse button 1 is pressed, the Command widget indicates that +it has been selected by reversing its foreground and background colors. +When the mouse button is released, the Command widget's notify +action is invoked, calling all functions on its callback list. If +the pointer is moved off of the widget before the pointer button is +released, the widget reverts to its normal foreground and background +colors, and releasing the pointer button has no effect. This behavior +allows the user to cancel an action. + + +Resources + + +When creating a Command widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + bitmap + Bitmap + Pixmap + + None + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + callback + Callback + XtCallbackList + + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cornerRoundPercent + CornerRoundPercent + Dimension + + 25 + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + NULL + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + encoding + Encoding + UnsignedChar + + XawTextEncoding8bit + + + font + Font + XFontStruct + + XtDefaultFont + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + graphic height + 2 * internalHeight + + + highlightThickness + Thickness + Dimension + A + 2 (0 if Shaped) + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + internalHeight + Height + Dimension + + 2 + + + internalWidth + Width + Dimension + + 4 + + + international + International + Boolean + C + False + + + justify + Justify + Justify + + XtJustifyCenter (center) + + + label + Label + String + + name of widget + + + leftBitmap + LeftBitmap + Bitmap + + None + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + resize + Resize + Boolean + + True + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + shapeStyle + ShapeStyle + ShapeStyle + + Rectangle + + + translations + Translations + TranslationTable + + See below + + + width + Width + Dimension + A + graphic width + 2 * internalWidth + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + _ + + + + +\" Resource Descriptions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Command Actions + + + +The Command widget supports the following actions: + + + + +Switching the button's interior between the foreground and background +colors with set, unset, and reset. + + + + +Processing application callbacks with notify + + + + +Switching the internal border between highlighted +and unhighlighted states with highlight and unhighlight + + + + + + +The following are the default translation bindings used by the +Command widget: + + + + + + + <EnterWindow>: highlight(\|) + <LeaveWindow>: reset(\|) + <Btn1Down>: set(\|) + <Btn1Up>: notify(\|) unset(\|) + + + + +The full list of actions supported by Command is: + + + + highlight(condition) + + + +Displays the internal highlight border in the color (foreground +or background ) that contrasts with the interior color of the +Command widget. The conditions WhenUnset and Always are +understood by this action procedure. If no argument is passed, +WhenUnset is assumed. + + + + + + unhighlight(\|) + + + +Displays the internal highlight border in the color (foreground +or background ) that matches the interior color of the +Command widget. + + + + + + set(\|) + + + +Enters the set state, in which notify is possible. This +action causes the button to display its interior in the +foreground color. The label or bitmap is displayed in the +background color. + + + + + + unset(\|) + + + +Cancels the set state and displays the interior of the button in the +background color. The label or bitmap is displayed in the +foreground color. + + + + + + reset(\|) + + + +Cancels any set or highlight and displays the interior of the +button in the background color, with the label or bitmap displayed +in the foreground color. + + + + + + notify(\|) + + + +When the button is in the set state this action calls all functions in +the callback list named by the callback resource. The value of +the call_data argument passed to these functions is undefined. + + + + + + + +A very common alternative to registering callbacks is to augment a +Command's translations with an action performing the desired +function. This often takes the form of: + + + + + + +*Myapp*save.translations: #augment <Btn1Down>,<Btn1Up>: Save() + + + + + +When a bitmap of depth greater that one (1) is specified the +set(), unset(), and reset() actions have no effect, +since there are no foreground and background colors used in a +multi-plane pixmap. + + + + + diff --git a/specs/Dialog.xml b/specs/Dialog.xml new file mode 100644 index 0000000..aff03d7 --- /dev/null +++ b/specs/Dialog.xml @@ -0,0 +1,692 @@ + +Dialog Widget + + + + + + + + + + +Application Header file <X11/Xaw/Dialog.h> + +Class Header file <X11/Xaw/DialogP.h> + +Class dialogWidgetClass + +Class Name Dialog + +Superclass Form + + + + + +The Dialog widget implements a commonly used interaction semantic to +prompt for auxiliary input from a user. For example, you can use a +Dialog widget when an application requires a small piece of information, +such as a filename, from the user. A Dialog widget, which is simply a +special case of the Form widget, provides a convenient way to create a +preconfigured form. + + + +The typical Dialog widget contains three areas. The first line +contains a description of the function of the Dialog widget, for +example, the string Filename:. The second line contains an area +into which the user types input. The third line can contain buttons +that let the user confirm or cancel the Dialog input. Any of these +areas may be omitted by the application. + + +Resources + + +When creating a Dialog widget instance, the following resources are +retrieved from the argument list or the resource database: + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + children + ReadOnly + WidgetList + R + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + defaultDistance + Thickness + int + + 4 + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + height + Height + Dimension + A + Enough space to contain all children + + + icon + Icon + Bitmap + + None + + + label + Label + String + + "label" + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + numChildren + ReadOnly + Cardinal + R + 0 + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + NULL + + + value + Value + String + + no value widget + + + width + Width + Dimension + A + Enough space to contain all children + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + _ + + + + + + + + + + + + + + + + + + + + + icon + + + +A pixmap image to be displayed immediately to the left of the +Dialog widget's label. + + + + + + label + + + +A string to be displayed at the top of the Dialog widget. + + + + + + + + + + + value + + + +An initial value for the string field that the user will enter text +into. By default, no text entry field is available to the user. +Specifying an initial value for value activates the text entry +field. If string input is desired, but no initial value is to be +specified then set this resource to "" (empty string). + + + + + + + + +Constraint Resources + + + +Each child of the Dialog widget may request special layout resources +be applied to it. These constraint resources allow the Dialog +widget's children to specify individual layout requirements. + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + bottom + Edge + XawEdgeType + + XawRubber + + + fromHoriz + Widget + Widget + + NULL (left edge of Dialog) + + + fromVert + Widget + Widget + + NULL (top edge of Dialog) + + + horizDistance + Thickness + int + + defaultDistance resource + + + left + Edge + XawEdgeType + + XawRubber + + + resizable + Boolean + Boolean + + FALSE + + + right + Edge + XawEdgeType + + XawRubber + + + top + Edge + XawEdgeType + + XawRubber + + + vertDistance + Thickness + int + + defaultDistance resource + + + + + + +bottom +left +right +top What to do with this edge of the child when + the parent is resized. This resource may be + any edgeType. See Layout Semantics for + details. + +fromHoriz +fromVert Which widget this child should be placed + underneath (or to the right of). If a value + of NULL is specified then this widget will be + positioned relative to the edge of the par- + ent. + +horizDistance +vertDistance The amount of space, in pixels, between this + child and its left or upper neighbor. + +resizable If this resource is False then the parent + widget will ignore all geometry request made + by this child. The parent may still resize + this child itself, however. + + + + + + + + +Layout Semantics + + +The Dialog widget uses two different sets of layout seman- +tics. One is used when initially laying out the children. +The other is used when the Dialog is resized. + + +The first layout method uses the fromVert mand fromHoriz +resources to place the children of the Dialog. A single +pass is made through the Dialog widget's children in the +order that they were created. Each child is then placed in +the Dialog widget below or to the right of the widget speci- +fied by the fromVert mand fromHoriz mresources. The distance +the new child is placed from its left or upper neighbor is +determined by the horizDistance mand vertDistance mresources. +This implies some things about how the order of creation +affects the possible placement of the children. The Form +widget registers a string to widget converter which does not +postpone conversion and does not cache conversion results. + + + +The second layout method is used when the Dialog is resized. +It does not matter what causes this resize, and it is possi- +ble for a resize to happen before the widget becomes visible +(due to constraints imposed by the parent of the Dialog). +This layout method uses the bottom , +top , left , and +right +resources. These resources are used to determine what will +happen to each edge of the child when the Dialog is resized. +If a value of XawChain +<something> + is specified, the the edge +of the child will remain a fixed distance from the chain +edge of the Dialog. For example if XawChainLeft +mis specified for the right mresource of a child +then the right edge +of that child will remain a fixed distance from the left +edge of the Dialog widget. If a value of XawRubber mis spec- +ified, that edge will grow by the same percentage that the +Dialog grew. For instance if the Dialog grows by 50% the +left edge of the child (if specified as XawRubber mwill be +50% farther from the left edge of the Dialog). One must be +very careful when specifying these resources, for when they +are specified incorrectly children may overlap or completely +occlude other children when the Dialog widget is resized. + + + + + + + + + + + + Edge Type + Resource Name + Description + + + + + XawChainBottom + ChainBottom + Edge remains a fixed distance from bottom of Dialog + + + XawChainLeft + ChainLeft + Edge remains a fixed distance from left of Dialog + + + XawChainRight + ChainRight + Edge remains a fixed distance from right of Dialog + + + XawChainTop + ChainTop + Edge remains a fixed distance from top of Dialog + + + XawRubber + Rubber + Edges will move a proportional distance + + + + + + +Example + + +If you wish to force the Dialog to never resize one or more of its children +then set left and right to XawChainLeft and +top and bottom to XawChainTop. This will cause +the child to remain a fixed distance from the top and left +edges of the Dialog, and to never resize. + + + +Special Considerations + + + +The Dialog widget automatically sets the top and bottom +resources for all Children that are subclasses of the Command widget, +as well as the widget children that are used to contain the label, +value, and icon. This policy allows the buttons at the +bottom of the Dialog to interact correctly with the predefined children, +and makes it possible for a client to simply create and manage a new +Command button without having to specify its constraints. + + + +The Dialog will also set fromLeft to the last button in the + +Dialog for each new button added to the Dialog widget. + + + +The automatically added constraints cannot be overridden, as they are +policy decisions of the Dialog widget. If a more flexible Dialog is +desired, the application is free to use the Form widget to create its +own Dialog policy. + + + + +Automatically Created Children. + + + +The Dialog uses Label widgets to contain the label and icon. +These widgets are named label and icon respectively. The +Dialog value is contained in an AsciiText widget whose name is +value. Using XtNameToWidget the application can change + +those resources associated with each of these widgets that are not +available through the Dialog widget itself. + + + + + + +Convenience Routines + + +To return the character string in the text field, use + + + + + String XawDialogGetValueString + Widget w + + + + + + + w + + + +Specifies the Dialog widget. + + + + + + + +This function returns a copy of the value string of the Dialog +widget. This string is allocated by the AsciiText widget and will +remain valid and unchanged until another call to + or an call on the +value widget, when the string will be automatically freed, and +a new string is returned. This string may be freed earlier by calling +the function . + + + + + +To add a new button to the Dialog widget use +. + + + + void XawDialogAddButton + Widget w + String name + XtCallbackProc func + XtPointer client_data + + + + + + + w + + + +Specifies the Dialog widget. + + + + + + name + + + +Specifies the name of the new Command button to be added to the Dialog. + + + + + + func + + + +Specifies a callback function to be called when this button is activated. If +NULL is specified then no callback is added. + + + + + + client_data + + + +Specifies the client_data to be passed to the func. + + + + + + + +This function is merely a shorthand for the code sequence: + + + + + +{ + Widget button = XtCreateManagedWidget(name, commandWidgetClass, w, NULL, ZERO); + XtAddCallback(button, XtNcallback, func, client_data); +} + + + + + + + diff --git a/specs/Form.xml b/specs/Form.xml new file mode 100644 index 0000000..a6e0a0c --- /dev/null +++ b/specs/Form.xml @@ -0,0 +1,531 @@ + +Form Widget + + + + + + + + + + +Application Header file <X11/Xaw/Form.h> + +Class Header file <X11/Xaw/FormP.h> + +Class formWidgetClass + +Class Name Form + +Superclass Constraint + + + + + +The Form widget can contain an arbitrary number of children or +subwidgets. The Form provides geometry management for its children, +which allows individual control of the position of each child. Any +combination of children can be added to a Form. The initial positions +of the children may be computed relative to the positions of previously +created children. When the Form is resized, it computes new positions and +sizes for its children. This computation is based upon information +provided when a child is added to the Form. + + + +The default width of the Form is the minimum width needed to +enclose the children after computing their initial layout, with a +margin of defaultDistance +at the right and bottom edges. If a width and height is assigned +to the Form that is too small for the layout, the children will +be clipped by the right and bottom edges of the Form. + + +Resources + + +When creating a Form widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + children + ReadOnly + WidgetList + R + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + defaultDistance + Thickness + int + + 4 + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + height + Height + Dimension + A + Enough space to contain all children + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + numChildren + ReadOnly + Cardinal + R + 0 + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + NULL + + + width + Width + Dimension + A + Enough space to contain all children + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + _ + + + + + + + + + + + + + + + + + + + + + + + + + + +Constraint Resources + + + +Each child of the Form widget may request special layout resources +be applied to it. These constraint resources allow the Form +widget's children to specify individual layout requirements. + + + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + bottom + Edge + XawEdgeType + + XawRubber + + + fromHoriz + Widget + Widget + + NULL (left edge of Form) + + + fromVert + Widget + Widget + + NULL (top edge of Form) + + + horizDistance + Thickness + int + + defaultDistance resource + + + left + Edge + XawEdgeType + + XawRubber + + + resizable + Boolean + Boolean + + FALSE + + + right + Edge + XawEdgeType + + XawRubber + + + top + Edge + XawEdgeType + + XawRubber + + + vertDistance + Thickness + int + + defaultDistance resource + + + + + + + + + + +bottom +left +right +top What to do with this edge of the child when + the parent is resized. This resource may be + any edgeType. See Layout Semantics for + details. + +fromHoriz +fromVert Which widget this child should be placed + underneath (or to the right of). If a value + of NULL is specified then this widget will be + positioned relative to the edge of the par- + ent. + +horizDistance +vertDistance The amount of space, in pixels, between this + child and its left or upper neighbor. + +resizable If this resource is False then the parent + widget will ignore all geometry request made + by this child. The parent may still resize + this child itself, however. + + + + +Layout Semantics + +The Form widget uses two different sets of layout semantics. +One is used when initially laying out the children. The +other is used when the Form is resized. + + +The first layout method uses the fromVert +and fromHoriz +resources to place the children of the Form. A single pass +is made through the Form widget's children in the order that +they were created. Each child is then placed in the Form +widget below or to the right of the widget specified by the +fromVert and fromHoriz +resources. The distance the new +child is placed from its left or upper neighbor is deter- +mined by the horizDistance and +vertDistance resources. This +implies some things about how the order of creation affects +the possible placement of the children. The Form widget +registers a string to widget converter which does not post- +pone conversion and does not cache conversion results. + + +The second layout method is used when the Form is resized. +It does not matter what causes this resize, and it is possi- +ble for a resize to happen before the widget becomes visible +(due to constraints imposed by the parent of the Form). +This layout method uses the bottom, +top, left, and +right +resources. These resources are used to determine what will +happen to each edge of the child when the Form is resized. +If a value of XawChain +<something> is specified, the the edge +of the child will remain a fixed distance from the +chain +edge of the Form. For example if XawChainLeft is specified +for the right resource of a child then the right edge of +that child will remain a fixed distance from the left edge +of the Form widget. If a value of XawRubber is specified, +that edge will grow by the same percentage that the Form +grew. For instance if the Form grows by 50% the left edge +of the child (if specified as XawRubber will be 50% farther +from the left edge of the Form). One must be very careful +when specifying these resources, for when they are specified +incorrectly children may overlap or completely occlude other +children when the Form widget is resized. + + + + + + + + + + + + + Edge Type + Resource Name + Description + + + + + XawChainBottom + ChainBottom + Edge remains a fixed distance from bottom of Form + + + XawChainLeft + ChainLeft + Edge remains a fixed distance from left of Form + + + XawChainRight + ChainRight + Edge remains a fixed distance from right of Form + + + XawChainTop + ChainTop + Edge remains a fixed distance from top of Form + + + XawRubber + Rubber + Edges will move a proportional distance + + + + + + +Example + + +If you wish to force the Form to never resize one or more of its +children, then set left and right to XawChainLeft and +top and bottom to XawChainTop. This will cause the +child to remain a fixed distance from the top and left edges of the +Form, and never to resize. + + + + +Convenience Routines + + +To force or defer a re-layout of the Form, use + + + + + + void XawFormDoLayout + Widget w + Boolean do_layout + + + + + + + w + + + +Specifies the Form widget. + + + + + + do_layout + + + +Specifies whether the layout of the Form widget is enabled (True) +or disabled (False). + + + + + + + +When making several changes to the children of a Form widget +after the Form has been realized, it is a good idea to disable +relayout until after all changes have been made. + + + + diff --git a/specs/Grip.xml b/specs/Grip.xml new file mode 100644 index 0000000..73dd5a7 --- /dev/null +++ b/specs/Grip.xml @@ -0,0 +1,357 @@ + +Grip Widget + + + + + + + + +Application header file <X11/Xaw/Grip.h> + +Class header file <X11/Xaw/GripP.h> + +Class gripWidgetClass + +Class Name Grip + +Superclass Simple + + + + +The Grip widget provides a small rectangular region in which user input +events (such as ButtonPress or ButtonRelease) may be handled. The most +common use for the Grip widget is as an attachment point for visually +repositioning an object, such as the pane border in a Paned widget. + + +Resources + + +When creating a Grip widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 0 + + + callback + Callback + Callback + + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + NULL + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + + 8 + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + international + International + Boolean + C + False + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + NULL + + + width + Width + Dimension + + 8 + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + + + + + + + + callback + + + +All routines on this list are called whenever the GripAction +action routine is invoked. The call_data contains all +information passed to the action routine. A detailed description +is given below in the Grip Actions section. + + + + + + + + + + + foreground + + + +A pixel value which indexes the widget's colormap to derive the color +used to flood fill the entire Grip widget. + + + + + + + + + + + + + + + + + +Grip Actions + + + +The Grip widget does not declare any default event translation bindings, +but it does declare a single action routine named GripAction. The + +client specifies an arbitrary event translation table, optionally giving +parameters to the GripAction routine. + + + +The GripAction routine executes the callbacks on the +callback list, passing as call_data a pointer to a +XawGripCallData structure, defined in the Grip widget's application +header file. + + + + + + + + + +typedef struct _XawGripCallData { + XEvent *event; + String *params; + Cardinal num_params; +} XawGripCallDataRec, *XawGripCallData, + GripCallDataRec, *GripCallData; /* supported for R4 compatibility */ + + + + + + + + +In this structure, the event is a pointer to the input event that +triggered the action. params and num_params give the string +parameters specified in the translation table for the particular event +binding. + + + + +The following is an example of a translation table that uses the GripAction: + + + + + + + + <Btn1Down>: GripAction(press) + <Btn1Motion>: GripAction(move) + <Btn1Up>: GripAction(release) + + +For a complete description of the format of translation tables, see the +X Toolkit Intrinsics - C Language Interface. + + + + diff --git a/specs/Label.xml b/specs/Label.xml new file mode 100644 index 0000000..65c4a92 --- /dev/null +++ b/specs/Label.xml @@ -0,0 +1,345 @@ + +Label Widget + + + + + + + + +Application header file <X11/Xaw/Label.h> + +Class header file <X11/Xaw/LabelP.h> + +Class labelWidgetClass + +Class Name Label + +Superclass Simple + + + + +A Label widget holds a graphic displayed within a +rectangular region of the screen. The graphic may be a +text string containing multiple lines of characters in an +8 bit or 16 bit character set (to be displayed with a +font), or in a multi-byte encoding (for use with a +fontset). The graphic may also be a bitmap or +pixmap. The Label widget will allow its graphic to be +left, right, or center justified. Normally, this widget +can be neither selected nor directly edited by the user. +It is intended for use as an output device only. + + +Resources + + +When creating a Label widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + bitmap + Bitmap + Pixmap + + None + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + NULL + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + encoding + Encoding + UnsignedChar + + XawTextEncoding8bit + + + font + Font + XFontStruct + + XtDefaultFont + + + fontSet + FontSet + XFontSet + + XtDefaultFontSet + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + graphic height + 2 * internalHeight + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + internalHeight + Height + Dimension + + 2 + + + internalWidth + Width + Dimension + + 4 + + + international + International + Boolean + C + False + + + justify + Justify + Justify + + XtJustifyCenter (center) + + + label + Label + String + + name of widget + + + leftBitmap + LeftBitmap + Bitmap + + None + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + resize + Resize + Boolean + + True + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + See above + + + width + Width + Dimension + A + graphic width + 2 * internalWidth + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/specs/List.xml b/specs/List.xml new file mode 100644 index 0000000..2c541dc --- /dev/null +++ b/specs/List.xml @@ -0,0 +1,872 @@ + +List Widget + + + + + + + + + + +Application header file <X11/Xaw/List.h> + +Class header file <X11/Xaw/ListP.h> + +Class listWidgetClass + +Class Name List + +Superclass Simple + + + + + + +The List widget contains a list of strings formatted into rows and +columns. When one of the strings is selected, it is highlighted, and the +List widget's Notify action is invoked, calling all routines on +its callback list. Only one string may be selected at a time. + + +Resources + + +When creating a List widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + callback + Callback + Callback + + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + columnSpacing + Spacing + Dimension + + 6 + + + cursor + Cursor + Cursor + + XC_left_ptr + + + cursorName + Cursor + String + + NULL + + + defaultColumns + Columns + int + + 2 + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + font + Font + FontStruct + + XtDefaultFont + + + fontSet + FontSet + XFontSet + + XtDefaultFontSet + + + forceColumns + Columns + Boolean + + False + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + Enough space to contain the list + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + internalHeight + Height + Dimension + + 2 + + + internalWidth + Width + Dimension + + 4 + + + international + International + Boolean + C + False + + + list + List + Pointer + + name of widget + + + longest + Longest + int + A + 0 + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + numberStrings + NumberStrings + int + A + computed for NULL terminated list + + + pasteBuffer + Boolean + Boolean + + False + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + rowSpacing + Spacing + Dimension + + 2 + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + See below + + + verticalList + Boolean + Boolean + + False + + + width + Width + Dimension + A + Enough space to contain the list + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + _ + + + + + + + + + + + + + + + callback + + + +All functions on this list are called whenever the notify action is +invoked. The call_data argument contains information about the element +selected and is described in detail in the List Callbacks section. + + + + + + + columnSpacing + + + + + + + + + + + rowSpacing + + + +The amount of space, in pixels, between each of the rows and columns +in the list. + + + + + + + + defaultColumns + + + +The default number of columns. This value is used when neither the +width nor the height of the List widget is specified or when +forceColumns is True. + + + + + + + + font + + + +The text font to use when displaying the list, when the +international resource is false. + + + + + + fontSet + + + +The text font set to use when displaying the list, when the +international resource is true. + + + + + + forceColumns + + + +Forces the default number of columns to be used regardless of the +List widget's current size. + + + + + + foreground + + + +A pixel value which indexes the widget's colormap to derive the color +used to paint the text of the list elements. + + + + + + + + \fPinternalHeight\fP + + + + + + + + + + + \fPinternalWidth\fP + + + +The margin, in pixels, between the edges of the list and the +corresponding edge of the List widget's window. + + + + + + list + + + +An array of text strings displayed in the List widget. If +numberStrings is zero (the default) then the list must be +NULL terminated. If a value is not specified for the list, then +numberStrings is set to 1, and the name of the widget is used as +the list, and longest is set to the length of the name of the +widget. The list is used in place, and must be available +to the List widget for the lifetime of this widget, or until it is +changed with or . + + + + + + + longest + + + +Specifies the width, in pixels, of the longest string in the current +list. The List widget will compute this value if zero (the default) +is specified. If this resource is set by hand, entries longer than this +will be clipped to fit. + + + + + + + numberStrings + + + +The number of strings in the current list. If a value of zero (the +default) is specified, the List widget will compute it. When computing +the number of strings the List widget assumes that the list is NULL +terminated. + + + + + + pasteBuffer + + + +If this resource is set to True then the name of the currently +selected list element will be put into CUT_BUFFER_0. + + + + + + + + + + + verticalList + + + +If this resource is set to True then the list elements will be +presented in column major order. + + + + + + + + +List Actions + + + +The List widget supports the following actions: + + + + +Highlighting and unhighlighting the list element under the +pointer with Set and Unset + + + + +Processing application callbacks with Notify + + + + + +The following is the default translation table used by the List Widget: + + + + + + + +<Btn1Down>,<Btn1Up>: Set(\|) Notify(\|) + + + + + +The full list of actions supported by List widget is: + + + + Set(\|) + + + +Sets the list element that is currently under the pointer. To +inform the user that this element is currently set, it is drawn with +foreground and background colors reversed. If this action is called when +there is no list element under the cursor, the currently set +element will be unset. + + + + + + Unset(\|) + + + +Cancels the set state of the element under the pointer, +and redraws it with normal foreground and background colors. + + + + + + Notify(\|) + + + +Calls all callbacks on the List widget's callback list. Information +about the currently selected list element is passed in the +call_data argument (see List Callbacks below). + + + + + + + +List Callbacks + + + +All procedures on the List widget's callback list will have a +XawListReturnStruct passed to them as call_data. The +structure is defined in the List widget's application header file. + + + + + + +typedef struct _XawListReturnStruct { + String string; /* string shown in the list. */ + int list_index; /* index of the item selected. */ +} XawListReturnStruct; + + + + +The list_index item used to be called simply index. +Unfortunately, this name collided with a global name defined on some +operating systems, and had to be changed. + + + + +Changing the List + + +To change the list that is displayed, use +XawListChange . + + + + void XawListChange + Widget w + String* list + intnitems, longest + Boolean resize + + + + + + + w + + + +Specifies the List widget. + + + + + + list + + + +Specifies the new list for the List widget to display. + + + + + + nitems + + + +Specifies the number of items in the list. If a value less than 1 +is specified, list must be NULL terminated, and the number of +items will be calculated by the List widget. + + + + + + longest + + + +Specifies the length of the longest item in the list in pixels. +If a value less than 1 is specified, the List widget will calculate the +value. + + + + + + resize + + + +Specifies a Boolean value that if True indicates that the +List widget should try to resize itself after making the change. +The constraints of the List widget's parent are always enforced, +regardless of the value specified here. + + + + + + + + +will unset all list elements that are currently set before +the list is actually changed. The list is used in place, and must +remain usable for the lifetime of the List widget, or until list +has been changed again with this function or with . + + + +Highlighting an Item + + +To highlight an item in the list, use +XawListHighlight . + + + + void XawListHighlight + Widget w + int item + + + + + + + w + + + +Specifies the List widget. + + + + + + item + + + +Specifies an index into the current list that indicates the item to be +highlighted. + + + + + + + +Only one item can be highlighted at a time. +If an item is already highlighted when + +is called, +the highlighted item is unhighlighted before the new item is highlighted. + + + +Unhighlighting an Item + + +To unhighlight the currently highlighted item in the list, use +XawListUnhighlight . + + + + void XawListUnhighlight + Widget w + + + + + + + w + + + +Specifies the List widget. + + + + + + + +Retrieving the Currently Selected Item + + +To retrieve the list element that is currently set, use +XawListShowCurrent . + + + + XawListReturnStruct *XawListShowCurrent + Widget w + + + + + + + w + + + +Specifies the List widget. + + + + + + + +XawListShowCurrent +returns a pointer to an +XawListReturnStruct +structure, +containing the currently highlighted item. +If the value of the index member is XAW_LIST_NONE, + +the string member is undefined, and no item is currently selected. + + + +Restrictions + + +Many programmers create a ``scrolled list'' by putting a List +widget with many entries as a child of a Viewport widget. The +List continues to create a window as big as its contents, but +that big window is only visible where it intersects the parent +Viewport's window. (I.e., it is ``clipped.'') + + + +While this is a useful technique, there is a serious drawback. +X does not support windows above 32,767 pixels in width or +height, but this height limit will be exceeded by a List's +window when the List has many entries (i.e., with a 12 point +font, about 3000 entries would be too many.) + + + + + + + diff --git a/specs/Makefile.am b/specs/Makefile.am new file mode 100644 index 0000000..8663da2 --- /dev/null +++ b/specs/Makefile.am @@ -0,0 +1,61 @@ + +if ENABLE_SPECS + +# Main DocBook/XML files (DOCTYPE book) +docbook = libXaw.xml + +# Included chapters, appendix, images +chapters = \ + AsciiSink.xml \ + AsciiSource.xml \ + AsciiText.xml \ + Box.xml \ + CH1.xml \ + CH2.xml \ + CH3.xml \ + CH4.xml \ + CH5.xml \ + CH6.xml \ + CH7.xml \ + Command.xml \ + Dialog.xml \ + Form.xml \ + Grip.xml \ + Label.xml \ + List.xml \ + MenuButton.xml \ + Paned.xml \ + Panner.xml \ + Porthole.xml \ + Repeater.xml \ + Scrollbar.xml \ + SimpleMenu.xml \ + Simple.xml \ + SmeBSB.xml \ + SmeLine.xml \ + Sme.xml \ + StripChart.xml \ + Template_private_header_file.xml \ + Template_public_header_file.xml \ + Template_widget_source_file.xml \ + Template.xml \ + TextActions_default_translation_bindings.xml \ + TextActions_text_widget_actions.xml \ + TextActions.xml \ + TextCustom.xml \ + TextFuncs.xml \ + TextSink.xml \ + TextSource.xml \ + Text.xml \ + Toggle.xml \ + TPage_Credits.xml \ + Tree.xml \ + Viewport.xml + +# The location where the DocBook/XML files and their generated formats are installed +shelfdir = $(docdir) + +# Generate DocBook/XML output formats with or without stylesheets +include $(top_srcdir)/docbook.am + +endif ENABLE_SPECS diff --git a/specs/MenuButton.xml b/specs/MenuButton.xml new file mode 100644 index 0000000..b7df723 --- /dev/null +++ b/specs/MenuButton.xml @@ -0,0 +1,567 @@ + +MenuButton Widget + + + + + + + + +Application Header file <X11/Xaw/MenuButton.h> + +Class Header file <X11/Xaw/MenuButtonP.h> + +Class menuButtonWidgetClass + +Class Name MenuButton + +Superclass Command + + + + +The MenuButton widget is an area, often rectangular, +that displays a graphic. The graphic may be a text +string containing multiple lines of characters in an 8 +bit or 16 bit character set (to be displayed with a +font), or in a multi-byte encoding (for use with +a fontset). The graphic may also be a bitmap or +pixmap. + + + +When the pointer cursor is on a MenuButton widget, the +MenuButton becomes highlighted by drawing a rectangle +around its perimeter. This highlighting indicates +that the MenuButton is ready for selection. When a +pointer button is pressed, the MenuButton widget will +pop up the menu named in the menuName resource. + + +Resources + + +When creating a MenuButton widget instance, +the following resources are retrieved from the argument list +or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + bitmap + Bitmap + Pixmap + + None + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + callback + Callback + XtCallbackList + + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cornerRoundPercent + CornerRoundPercent + Dimension + + 25 + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + None + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + encoding + Encoding + UnsignedChar + + XawTextEncoding8bit + + + font + Font + XFontStruct + + XtDefaultFont + + + fontSet + FontSet + XFontSet + + XtDefaultFontSet + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + graphic height + 2 * internalHeight + + + highlightThickness + Thickness + Dimension + A + 2 (0 if Shaped) + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + internalHeight + Height + Dimension + + 2 + + + internalWidth + Width + Dimension + + 4 + + + international + International + Boolean + C + False + + + justify + Justify + Justify + + XtJustifyCenter (center) + + + label + Label + String + + name of widget + + + leftBitmap + LeftBitmap + Bitmap + + None + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + menuName + MenuName + String + + "menu" + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + resize + Resize + Boolean + + True + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + shapeStype + ShapeStyle + ShapeStyle + + Rectangle + + + translations + Translations + TranslationTable + + See below + + + width + Width + Dimension + A + graphic width + 2 * internalWidth + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + _ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + menuName + + + +The name of a popup shell to popup as a menu. The MenuButton +will search for this name using XtNameToWidget starting +with itself as the reference widget. If the search is +unsuccessful the widget will continue up the widget tree using +each of its ancestors as the reference widget passed to +XtNameToWidget. If no widget of called menuName is +found by this algorithm, the widget will print a warning message +and give up. When the menu is found it will be popped up +exclusive and spring_loaded. The MenuButton widget does not +copy the value of this resource into newly allocated memory. The +application programmer must pass the resource value in +nonvolatile memory. + + + + + + + + + + + + + + + +MenuButton Actions + + + +The MenuButton widget supports the following actions: + + + + +Switching the button between the foreground and background +colors with set and unset + + + + +Processing application callbacks with notify + + + + +Switching the internal border between highlighted +and unhighlighted states with highlight and unhighlight + + + + +Popping up a menu with PopupMenu + + + + + +The following are the default translation bindings used by the +MenuButton widget: + + + + + + + + <EnterWindow>: highlight(\|) + <LeaveWindow>: reset(\|) + <BtnDown>: reset(\|) PopupMenu(\) + + + + +MenuButton Actions + + +The full list of actions supported by MenuButton is: + + + + highlight(condition) + + + +Displays the internal highlight border in the color (foreground +or background ) that contrasts with the interior color of the +Command widget. The conditions WhenUnset and Always are +understood by this action procedure. If no argument is passed, +WhenUnset is assumed. + + + + + + unhighlight(\|) + + + +Displays the internal highlight border in the color (XtNforeground +or background ) that matches the interior color of the +MenuButton widget. + + + + + + set(\|) + + + +Enters the set state, in which notify is possible. This +action causes the button to display its interior in the +foreground color. The label or bitmap is displayed in the +background color. + + + + + + unset(\|) + + + +Cancels the set state and displays the interior of the button in the +background color. The label or bitmap is displayed in the +foreground color. + + + + + + reset(\|) + + + +Cancels any set or highlight and displays the interior of the +button in the background color, with the label displayed in the +foreground color. + + + + + + notify(\|) + + + +When the button is in the set state this action calls all functions in +the callback list named by the callback resource. The value of +the call_data argument in these callback functions is undefined. + + + + + + PopupMenu(\|) + + + +Pops up the menu specified by the menuName resource. + + + + + + + +The MenuButton widget does not place a server grab on itself. +Instead, PopupMenu is registered as a grab action. +As a result, clients which popup menus without using XtMenuPopup +or MenuPopup or PopupMenu in translations will fail to have a grab active. +They should make a call to XtRegisterGrabAction on the appropriate action +in the application initialization routine, or use a different translation. + + + + + diff --git a/specs/Paned.xml b/specs/Paned.xml new file mode 100644 index 0000000..6ab2f1d --- /dev/null +++ b/specs/Paned.xml @@ -0,0 +1,1213 @@ + +Paned Widget + + + + + + + + + + +Application Header file <X11/Xaw/Paned.h> + +Class Header file <X11/Xaw/PanedP.h> + +Class panedWidgetClass + +Class Name Paned + +Superclass Constraint + + + + + +The Paned widget manages children in a vertically or horizontally +tiled fashion. The panes may be dynamically resized by the user by +using the grips that appear near the right or bottom edge of the +border between two panes. + + + +The Paned widget may accept any widget class as a pane except +Grip. Grip widgets have a special meaning for the Paned widget, and +adding a Grip as its own pane will confuse the Paned widget. + + +Using the Paned Widget + + + +The grips allow the panes to be resized by the user. The semantics of +how these panes resize is somewhat complicated, and warrants further +explanation here. When the mouse pointer is positioned on a grip and +pressed, an arrow is displayed that indicates the pane that is to be to +be resized. While keeping the mouse button down, the user can move the +grip up and down (or left and right). This, in turn, changes the size +of the pane. The size of the Paned widget will not change. Instead, +it chooses another pane (or panes) to resize. For more details on which +pane it chooses to resize, see Layout Semantics. + + + +One pointer binding allows the border between two panes to be moved, +without affecting any of the other panes. When this occurs the pointer +will change to an arrow that points along the pane border. + + + +The default bindings for the Paned widget's grips are: + + + + + + + + Mouse button + Pane to Resize - Vertical + Pane to Resize - Horizontal + + + + + 1 (left) + above the grip + left of the grip + + + 2 (middle) + adjust border + adjust border + + + 3 (right) + below the grip + right of the grip + + + _ + + + + + + + +Resources + + +When creating a Paned widget instance, the following resources are +retrieved from the argument list or the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + betweenCursor + Cursor + Cursor + A + Depends on orientation + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + children + ReadOnly + WidgetList + R + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cursor + Cursor + Cursor + + None + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + gripCursor + Cursor + Cursor + A + Depends on orientation + + + gripIndent + GripIndent + Position + + 10 + + + gripTranslations + Translations + TranslationTable + + see below + + + height + Height + Dimension + A + Depends on orientation + + + horizontalBetweenCursor + Cursor + Cursor + + sb_up_arrow + + + horizontalGripCursor + Cursor + Cursor + + sb_h_double_arrow + + + internalBorderColor + BorderColor + Pixel + + XtDefaultForeground + + + internalBorderWidth + BorderWidth + Dimension + + 1 + + + leftCursor + Cursor + Cursor + + sb_left_arrow + + + lowerCursor + Cursor + Cursor + + sb_down_arrow + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + numChildren + ReadOnly + Cardinal + R + 0 + + + orientation + Orientation + Orientation + + XtorientVertical + + + refigureMode + Boolean + Boolean + + True + + + rightCursor + Cursor + Cursor + + sb_right_arrow + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + NULL + + + upperCursor + Cursor + Cursor + + sb_up_arrow + + + verticalBetweenCursor + Cursor + Cursor + + sb_left_arrow + + + verticalGripCursor + Cursor + Cursor + + sb_v_double_arrow + + + width + Width + Dimension + A + Depends on orientation + + + x + Paned + Position + + 0 + + + y + Paned + Position + + 0 + + + _ + + + + + + + + + + + + + + + + + cursor + + + +The cursor to use when the mouse pointer is over the Paned widget, but +not in any of its children (children may also inherit this cursor). It +should be noted that the internal borders are actually part of the Paned +widget, not the children. + + + + + + + + gripCursor + + + +The cursor to use when the grips are not active. The default value is +verticalGripCursor or horizontalGripCursor depending on +the orientation of the Paned widget. + + + + + + gripIndent + + + +The amount of space left between the right (or bottom) edge of the +Paned widget and all the grips. + + + + + + gripTranslation + + + +Translation table that will be applied to all grips. + + + + + + + horizontalBetweenCursor + + + + + + + + + + + verticalBetweenCursor + + + +The cursor to be used for the grip when changing the boundary between +two panes. These resources allow the cursors to be different +depending on the orientation of the Paned widget. + + + + + + horizontalGripCursor + + + + + + + + + + + verticalGripCursor + + + +The cursor to be used for the grips when they are not active. These +resources allow the cursors to be different depending on the +orientation of the Paned widget. + + + + + + internalBorderColor + + + +A pixel value which indexes the widget's colormap to derive the internal +border color of the widget's window. The class name of this resource +allows Paned*BorderColor: blue to set the internal border color +for the Paned widget. An optimization is invoked if +internalBorderColor and background are the same, and the +internal borders are not drawn. internalBorderWidth is still left +between the panes, however. + + + + + + internalBorderWidth + + + +The width of the internal borders. This is the amount of space left +between the panes. The class name of this resource allows +Paned*BorderWidth: 3 to set the internal border width for the +Paned widget. + + + + + + leftCursor + + + + + + + + + + + rightCursor + + + +The cursor used to indicate which is the important pane to resize +when the Paned widget is oriented horizontally. + + + + + + lowerCursor + + + + + + + + + + + upperCursor + + + +The cursor used to indicate which is the important pane to resize +when the Paned widget is oriented vertically. + + +This is not the same as the number of panes, since this also contains a +grip for some of the panes, use to retrieve the +number of panes. + + + + + + orientation + + + +The orientation to stack the panes. This value can be either +XtorientVertical or XtorientHorizontal. + + + + + + + + + + refigureMode + + + +This resource allows pane layout to be suspended. If this value is +False, then no layout actions will be taken. This may improve +efficiency when adding or removing more than one pane from the Paned +widget. + + + + + + + + + + + +Constraint Resources + + + +Each child of the Paned widget may request special layout resources +be applied to it. These constraint resources allow the Paned +widget's children to specify individual layout requirements. + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + allowResize + Boolean + Boolean + + False + + + max + Max + Dimension + + Infinity + + + min + Min + Dimension + + Height of Grips + + + preferredPaneSize + PreferredPaneSize + Dimension + + ask child + + + resizeToPreferred + Boolean + Boolean + + False + + + showGrip + ShowGrip + Boolean + + True + + + skipAdjust + Boolean + Boolean + + False + + + _ + + + + + + + + allowResize + + + +If this value is False the the Paned widget will disallow all +geometry requests from this child. + + + + + + max + + + + + + + + + + + min + + + +The absolute maximum or minimum size for this pane. These values will +never be overridden by the Paned widget. This may cause some panes to be +pushed off the bottom (or right) edge of the paned widget. + + + + + + preferredPaneSize + + + +Normally the paned widget makes a QueryGeometry call on a child to +determine the preferred size of the child's pane. There are times +when the application programmer or the user has a better idea of the +preferred size of a pane. Setting this resource causes the value +passed to be interpreted as the preferred size, in pixels, of this pane. + + + + + + resizeToPreferred + + + +Determines whether or not to resize each pane to its preferred size +when the Paned widget is resized. See Layout Semantics for details. + + + + + + showGrip + + + +If True then a grip will be shown for this pane. The grip +associated with a pane is either below or to the right of the pane. No +grip is ever shown for the last pane. + + + + + + skipAdjust + + + +This resource is used to determine which pane is forced to be resized. +Setting this value to True makes this pane less likely to be +forced to be resized. See Layout Semantics for details. + + + + + + + +Layout Semantics + + + +In order to make effective use of the Paned widget it is helpful to know +the rules it uses to determine which child will be resized in any given +situation. There are three rules used to determine which child is +resized. While these rules are always the same, the panes that are +searched can change depending upon what caused the relayout. + + + + +Layout Rules + + + + 1 + + + +Do not let a pane grow larger than its max or smaller than its +min. + + + + + + 2 + + + +Do not adjust panes with skipAdjust set. + + + + + + 3 + + + +Do not adjust panes away from their preferred size, although moving one +closer to its preferred size is fine. + + + + + + + +When searching the children the Paned widget looks for panes that +satisfy all the rules, and if unsuccessful then it eliminates rule 3 +and then 2. Rule 1 is always enforced. + + + +If the relayout is due to a resize or change in management then the +panes are searched from bottom to top. If the relayout is due to grip +movement then they are searched from the grip selected in the direction +opposite the pane selected. + + +Resizing Panes from a Grip Action + + +The pane above the grip is resized by invoking the GripAction with +UpLeftPane specified. The panes below the grip are each checked +against all rules, then rules 2 and 1 and finally against rule 1 only. +No pane above the chosen pane will ever be resized. + + + +The pane below the grip is resized by invoking the GripAction with +LowRightPane specified. The panes above the grip are each +checked in this case. No pane below the chosen pane will ever be resized. + + + +Invoking GripAction with ThisBorderOnly specified just moves the +border between the panes. No other panes are ever resized. + + + +Resizing Panes after the Paned widget is resized. + + +When the Pane widget is resized it must determine a new size for each +pane. There are two methods of doing this. The Paned widget can either +give each pane its preferred size and then resize the panes to fit, or +it can use the current sizes and then resize the panes to fit. The +resizeToPreferred resource allows the application to tell the +Paned widget whether to query the child about its preferred size +(subject to the the preferredPaneSize) or to use the current size +when refiguring the pane locations after the pane has been resized. + + + +There is one special case. All panes assume they should resize to +their preferred size until the Paned widget becomes visible to the user. + + + +Managing Children and Geometry Management + + +The Paned widget always resizes its children to their preferred sizes when +a new child is managed, or a geometry management request is honored. +The Paned widget will first attempt to resize itself to contain its +panes exactly. If this is not possible then it will hunt through the +children, from bottom to top (right to left), for a pane to resize. + + + +Special Considerations + + +When a user resizes a pane with the grips, the Paned widget assumes that +this new size is the preferred size of the pane. + + + + +Grip Translations + + +The Paned widget has no action routines of its own, as all actions are +handled through the grips. The grips are each assigned a default +Translation table. + + + + + + + + <Btn1Down>: GripAction(Start, UpLeftPane) + + <Btn2Down>: GripAction(Start, ThisBorderOnly) + <Btn3Down>: GripAction(Start, LowRightPane) + <Btn1Motion>: GripAction(Move, UpLeftPane) + <Btn2Motion>: GripAction(Move, ThisBorderOnly) + <Btn3Motion>: GripAction(Move, LowRightPane) + Any<BtnUp>: GripAction(Commit) + + + + + +The Paned widget interprets the GripAction as taking two arguments. + +The first argument may be any of the following: + + + + Start + + + +Sets up the Paned widget for resizing and changes the cursor of the +grip. The second argument determines which pane will be resized, and +can take on any of the three values shown above. + + + + + + Move + + + +The internal borders are drawn over the current pane locations to +animate where the borders would actually be placed if you were to move +this border as shown. The second argument must match the second argument +that was passed to the Start action, that began this process. If +these arguments are not passed, the behavior is undefined. + + + + + + Commit + + + +This argument causes the Paned widget to commit the changes selected +by the previously started action. The cursor is changed back to the +grip's inactive cursor. No second argument is needed in this case. + + + + + + + +Convenience Routines + + + + +To enable or disable a child's request for pane resizing, +use +XawPanedAllowResize : + + + + void XawPanedAllowResize + Widget w + Boolean allow_resize + + + + + + + w + + + +Specifies the child pane. + + + + + + allow_resize + + + +Specifies whether or not resizing requests for this child will be +granted by the Paned widget. + + + + + + + +If allow_resize is True, the Paned widget allows geometry +requests from the child to change the pane's height. If allow_resize +is False, the Paned widget ignores geometry requests from the +child to change the pane's height. The default state is True +before the Pane is realized and False after it is realized. +This procedure is equivalent to changing the allowResize +constraint resource for the child. + + + + + +To change the minimum and maximum height settings for a pane, use +XawPanedSetMinMax : + + + + void XawPanedSetMinMax + Widget w + intmin, max + + + + + + + w + + + +Specifies the child pane. + + + + + + min + + + +Specifies the new minimum height of the child, expressed in pixels. + + + + + + max + + + +Specifies new maximum height of the child, expressed in pixels. + + + + + + + +This procedure is equivalent to setting the min and max +constraint resources for the child. + + + + + +To retrieve the minimum and maximum height settings for a pane, use +XawPanedGetMinMax : + + + + void XawPanedGetMinMax + Widget w + int*min_return, *max_return + + + + + + + w + + + +Specifies the child pane. + + + + + + min_return + + + +Returns the minimum height of the child, expressed in pixels. + + + + + + max_return + + + +Returns the maximum height of the child, expressed in pixels. + + + + + + + +This procedure is equivalent to getting the min and max +resources for this child child. + + + + + + +To enable or disable automatic recalculation of pane sizes and positions, +use +XawPanedSetRefigureMode : + + + + void XawPanedSetRefigureMode + Widget w + Boolean mode + + + + + + + w + + + +Specifies the Paned widget. + + + + + + mode + + + +Specifies whether the layout of the Paned widget is enabled (True) +or disabled (False). + + + + + + + +When making several changes to the children of a Paned widget +after the Paned has been realized, it is a good idea to disable +relayout until after all changes have been made. + + + + + +To retrieve the number of panes in a paned widget use +: + + + + int XawPanedGetNumSub + Widget w + + + + + + + w + + + +Specifies the Paned widget. + + + + + + + +This function returns the number of panes in the Paned widget. This is +not the same as the number of children, since the grips are also +children of the Paned widget. + + + + diff --git a/specs/Panner.xml b/specs/Panner.xml new file mode 100644 index 0000000..f886af0 --- /dev/null +++ b/specs/Panner.xml @@ -0,0 +1,734 @@ + +Panner Widget + + + + + + + + + + +Application header file <X11/Xaw/Panner.h> + +Class header file <X11/Xaw/PannerP.h> + +Class pannerWidgetClass + +Class Name Panner + +Superclass Simple + + + + + +A Panner widget is a rectangle, called the +``canvas,'' on which another rectangle, the ``slider,'' moves in two +dimensions. It is often used with a Porthole widget to move, or +``scroll,'' a third widget in two dimensions, in which case the +slider's size and position gives feedback as to what portion of +the third widget is visible. + + + +The slider may be scrolled around the canvas by pressing, +dragging, and releasing Button1; the default translation also +enables scrolling via arrow keys and some other keys. While +scrolling is in progress, the application receives notification +through callback procedures. Notification may be done either +continuously whenever the slider moves or discretely whenever the +slider has been given a new location. + + +Resources + + +When creating a Panner widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + allowOff + AllowOff + Boolean + + False + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + backgroundStipple + BackgroundStipple + String + + NULL + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + canvasHeight + CanvasHeight + Dimension + + 0 + + + canvasWidth + CanvasWidth + Dimension + + 0 + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + NULL + + + defaultScale + DefaultScale + Dimension + + 8 + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + depends on orientation + + + internalSpace + InternalSpace + Dimension + + 4 + + + international + International + Boolean + C + False + + + lineWidth + LineWidth + Dimension + + 0 + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + reportCallback + ReportCallback + Callback + + NULL + + + resize + Resize + Boolean + + True + + + rubberBand + RubberBand + Boolean + + False + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + shadowColor + ShadowColor + Pixel + + XtDefaultForeground + + + shadowThickness + ShadowThickness + Dimension + + 2 + + + sliderX + SliderX + Position + + 0 + + + sliderY + SliderY + Position + + 0 + + + sliderHeight + SliderHeight + Dimension + + 0 + + + sliderWidth + SliderWidth + Dimension + + 0 + + + translations + Translations + TranslationTable + + See below + + + width + Width + Dimension + A + depends on orientation + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + + + allowOff + + + +Whether to allow the edges of the slider to go off the edges of the canvas. + + + + + + + + + backgroundStipple + + + +The name of a bitmap pattern to be used as the background for +the area representing the canvas. + + + + + + + + + canvasHeight + + + + + + + + + + + canvasWidth + + + +The size of the canvas. + + + + + + + + + defaultScale + + + +The percentage size that the Panner widget should have relative +to the size of the canvas. + + + + + + + + foreground + + + +A pixel value which indexes the widget's colormap to derive the color +used to draw the slider. + + + + + + + internalSpace + + + +The width of internal border in pixels between a slider representing the +full size of the canvas +and the edge of the Panner widget. + + + + + + + lineWidth + + + +The width of the lines in the rubberbanding rectangle when rubberbanding +is in effect instead of continuous scrolling. The default is 0. + + + + + + + + + reportCallback + + + +All functions on this callback list are called when the +notify action is invoked. See the Panner Actions section +for details. + + + + + + resize + + + +Whether or not to resize the panner whenever the canvas size is changed so +that the defaultScale is maintained. + + + + + + rubberBand + + + +Whether or not scrolling should be discrete (only moving a rubberbanded +rectangle until the scrolling is done) or continuous (moving the slider +itself). This controls whether or not the move action procedure also +invokes the notify action procedure. + + + + + + + + shadowColor + + + +The color of the shadow underneath the slider. + + + + + + shadowThickness + + + +The width of the shadow underneath the slider. + + + + + + sliderX + + + + + + + + + + + sliderY + + + +The location of the slider in the coordinates of the canvas. + + + + + + sliderHeight + + + + + + + + + + + sliderWidth + + + +The size of the slider. + + + + + + + + +Panner Actions + + + +The actions supported by the Panner widget are: + + + + + start() + + + +This action begins movement of the slider. + + + + + + stop() + + + +This action ends movement of the slider. + + + + + + abort() + + + +This action ends movement of the slider and restores it to the position it +held when the start action was invoked. + + + + + + move() + + + +This action moves the outline of the slider (if the rubberBand resource +is True) or the slider itself (by invoking the notify +action procedure). + + + + + + page(xamount,yamount) + + + +This action moves the slider by the specified amounts. The format +for the amounts is a signed or unsigned floating-point number (e.g., +1.0 +or \-.5) followed +by either p indicating pages (slider sizes), or c indicating +canvas sizes. Thus, page(+0,+.5p) represents vertical movement down +one-half the height of the slider and page(0,0) represents moving to +the upper left corner of the canvas. + + + + + + notify() + + + +This action informs the application of the slider's current position by +invoking the reportCallback functions registered by the application. + + + + + + set(what,value) + + + +This action changes the behavior of the Panner. The what argument +must currently be the string rubberband and controls the value of +the rubberBand resource. The value argument +may have one of the values on, off, or toggle. + + + + + + + + +The default bindings for Panner are: + + + + + + + <Btn1Down>: start(\|) + <Btn1Motion>: move(\|) + <Btn1Up>: notify(\|) stop(\|) + <Btn2Down>: abort(\|) + <Key>KP_Enter: set(rubberband,toggle) + <Key>space: page(+1p,+1p) + <Key>Delete: page(\-1p,\-1p) + <Key>BackSpace: page(\-1p,\-1p) + <Key>Left: page(\-.5p,+0) + <Key>Right: page(+.5p,+0) + <Key>Up: page(+0,\-.5p) + <Key>Down: page(+0,+.5p) + <Key>Home: page(0,0) + + + + +Panner Callbacks + + + +The functions registered on the reportCallback list are invoked by +the notify action as follows: + + + + void ReportProc + Widget panner + XtPointer client_data + XtPointer report + + + + + + + + panner + + + +Specifies the Panner widget. + + + + + panner + + + +Specifies the client data. + + + + + panner + + + +Specifies a pointer to an XawPannerReport structure containing +the location and size of the slider and the size of the canvas. + + + + + + + diff --git a/specs/Porthole.xml b/specs/Porthole.xml new file mode 100644 index 0000000..0452578 --- /dev/null +++ b/specs/Porthole.xml @@ -0,0 +1,306 @@ + +Porthole Widget + + + + + + + + + + +Application Header file <X11/Xaw/Porthole.h> + +Class Header file <X11/Xaw/PortholeP.h> + +Class portholeWidgetClass + +Class Name Porthole + +Superclass Composite + + + + + +The Porthole widget provides geometry management of a list of arbitrary +widgets, only one of which may be managed at any particular time. +The managed child widget is reparented within the porthole and is moved around +by the application (typically under the control of a Panner widget). + + +Resources + + +When creating a Porthole widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + children + ReadOnly + WidgetList + R + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + height + Height + Dimension + A + see Layout Semantics + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + numChildren + ReadOnly + Cardinal + R + 0 + + + reportCallback + ReportCallback + Callback + + NULL + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + NULL + + + width + Width + Dimension + A + see Layout Semantics + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + _ + + + + + + + + + + + + + + + + + + + + + + reportCallback + + + +A list of functions to invoke whenever the managed child widget changes +size or position. + + + + + + + + + + + +Layout Semantics + + + +The Porthole widget allows its managed child to request any size +that is as large +or larger than the Porthole itself and any location so long as the child +still obscures all of the Porthole. This widget typically is used with a +Panner widget. + + + +Porthole Callbacks + + + +The functions registered on the reportCallback list are invoked whenever +the managed child changes size or position: + + + + void ReportProc + Widget porthole + XtPointer client_data + XtPointer report + + + + + + + porthole + + + +Specifies the Porthole widget. + + + + + client_data + + + +Specifies the client data. + + + + + report + + + +Specifies a pointer to an XawPannerReport structure containing +the location and size of the slider and the size of the canvas. + + + + + + diff --git a/specs/Repeater.xml b/specs/Repeater.xml new file mode 100644 index 0000000..289e14d --- /dev/null +++ b/specs/Repeater.xml @@ -0,0 +1,558 @@ + +Repeater Widget + + + + + + + + +Application header file <X11/Xaw/Repeater.h> + +Class header file <X11/Xaw/RepeaterP.h> + +Class repeaterWidgetClass + +Class Name Repeater + +Superclass Command + + + + +The Repeater widget is a subclass of the Command widget; see the +Command documentation for details. The difference is that the Repeater can call its +registered callbacks repeatedly, at an increasing rate. The default translation +does so for the duration the user holds down pointer button 1 while the pointer +is on the Repeater. + + +Resources + + +When creating a Repeater widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + bitmap + Bitmap + Pixmap + + None + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + callback + Callback + XtCallbackList + + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cornerRoundPercent + CornerRoundPercent + Dimension + + 25 + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + NULL + + + decay + Decay + Int + + 5 + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + encoding + Encoding + UnsignedChar + + XawTextEncoding8bit + + + flash + Boolean + Boolean + + False + + + font + Font + XFontStruct + + XtDefaultFont + + + fontSet + FontSet + XFontSet + + XtDefaultFontSet + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + graphic height + 2 * internalHeight + + + highlightThickness + Thickness + Dimension + A + 2 (0 if Shaped) + + + initialDelay + Delay + Int + + 200 + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + internalHeight + Height + Dimension + + 2 + + + internalWidth + Width + Dimension + + 4 + + + international + International + Boolean + C + False + + + justify + Justify + Justify + + XtJustifyCenter (center) + + + label + Label + String + + name of widget + + + leftBitmap + LeftBitmap + Bitmap + + None + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + minimumDelay + MinimumDelay + Int + + 10 + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + repeatDelay + Delay + Int + + 50 + + + resize + Resize + Boolean + + True + + + screen + Screen + Pointer + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + shapeStyle + ShapeStyle + ShapeStyle + + Rectangle + + + startCallback + StartCallback + Callback + + NULL + + + stopCallback + StopCallback + Callback + + NULL + + + translations + Translations + TranslationTable + + See below + + + width + Width + Dimension + A + graphic width + 2 * internalWidth + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + +\" Resource Descriptions + + + + + + + + + + + + + + + + + decay + + + +The number of milliseconds that should be subtracted from each succeeding +interval while the Repeater button is being held down until the interval +has reached minimumDelay milliseconds. + + + + + + + + + flash + + + +Whether or not to flash the Repeater button whenever the timer goes off. + + + + + + + + + + + initialDelay + + + +The number of milliseconds between the beginning of the Repeater button +being held down and the first invocation of the callback function. + + + + + + + + + + + + + minimumDelay + + + +The minimum time between callbacks in milliseconds. + + + + + + + + repeatDelay + + + +The number of milliseconds between each callback after the first (minus an +increasing number of decays). + + + + + + + + + + startCallback + + + +The list of functions to invoke by the start action (typically +when the Repeater button is first pressed). The callback data parameter +is set to NULL. + + + + + + stopCallback + + + +The list of functions to invoke by the stop action (typically +when the Repeater button is released). The callback data parameter +is set to NULL. + + + + + + + + + +Repeater Actions + + + +The Repeater widget supports the following actions beyond those of the Command +button: + + + + start() + + + +This invokes the functions on the startCallback and callback lists +and sets a timer to go off in initialDelay milliseconds. The timer +will cause the callback functions to be invoked with increasing +frequency until the stop action occurs. + + + + + + stop() + + + +This invokes the functions on the stopCallback list and prevents any +further timers from occuring until the next start action. + + + + + + + + + +The following are the default translation bindings used by the +Repeater widget: + + + + + + + <EnterWindow>: highlight(\|) + <LeaveWindow>: unhighlight(\|) + <Btn1Down>: set(\|) start(\|) + <Btn1Up>: stop(\|) unset(\|) + + + + + + + + diff --git a/specs/Scrollbar.xml b/specs/Scrollbar.xml new file mode 100644 index 0000000..f5d0553 --- /dev/null +++ b/specs/Scrollbar.xml @@ -0,0 +1,884 @@ + +Scrollbar Widget + + +Application header file <X11/Xaw/Scrollbar.h> +Class header file <X11/Xaw/ScrollbarP.h> +Class scrollbarWidgetClass +Class Name Scrollbar +Superclass Simple + + + +A Scrollbar widget is a rectangle, called the ``canvas,'' on +which another rectangle, the ``thumb,'' moves in one +dimension, either vertically or horizontally. A Scrollbar +can be used alone, as a value generator, or it can be used +within a composite widget (for example, a Viewport). When a +Scrollbar is used to move, or ``scroll,'' the contents of +another widget, the size and the position of the thumb usually give +feedback as to what portion of the other widget's contents +are visible. + + + +Each pointer button invokes a specific action. Pointer +buttons 1 and 3 do not move the thumb automatically. +Instead, they return the pixel position of the cursor on the +scroll region. When pointer button 2 is clicked, the thumb +moves to the current pointer position. When pointer button +2 is held down and the pointer is moved, the thumb follows +the pointer. + + + +The pointer cursor in the scroll region changes depending on the current +action. When no pointer button is pressed, the cursor appears as a +double-headed arrow that points in the direction that scrolling can +occur. When pointer button 1 or 3 is pressed, the cursor appears as a +single-headed arrow that points in the logical direction that the thumb +will move. When pointer button 2 is pressed, the cursor +appears as an arrow that points to the top or the left of the thumb. + + + +When the user scrolls, the application receives notification +through callback procedures. For both discrete scrolling actions, the +callback returns the Scrollbar widget, the client_data, and the pixel +position of the pointer when the button was released. For continuous +scrolling, the callback routine returns the scroll bar widget, the +client data, and the current relative position of the thumb. When the +thumb is moved using pointer button 2, the callback procedure is invoked +continuously. When either button 1 or 3 is pressed, the callback +procedure is invoked only when the button is released and the client +callback procedure is responsible for moving the thumb. + + + +Resources + + +When creating a Scrollbar widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + colormap + Colormap + Colormap + + parent's Colormap + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + NULL + + + depth + Depth + int + C + parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + depends on orientation + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + international + International + Boolean + C + False + + + jumpProc + Callback + XtCallbackList + + NULL + + + length + Length + Dimension + + 1 + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + minimumThumb + MinimumThumb + Dimension + + 7 + + + orientation + Orientation + Orientation + + XtorientVertical (vertical) + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + screen + Screen + Screen + R + parent's Screen + + + scrollDCursor + Cursor + Cursor + + XC_sb_down_arrow + + + scrollHCursor + Cursor + Cursor + + XC_sb_h_double_arrow + + + scrollLCursor + Cursor + Cursor + + XC_sb_left_arrow + + + scrollProc + Callback + XtCallbackList + + NULL + + + scrollRCursor + Cursor + Cursor + + XC_sb_right_arrow + + + scrollUCursor + Cursor + Cursor + + XC_sb_up_arrow + + + scrollVCursor + Cursor + Cursor + + XC_sb_v_arrow + + + sensitive + Sensitive + Boolean + + True + + + shown + Shown + Float + + 0.0 + + + thickness + Thickness + Dimension + + 14 + + + thumb + Thumb + Bitmap + + GreyPixmap + + + thumbProc + Callback + XtCallbackList + + NULL + + + topOfThumb + TopOfThumb + Float + + 0.0 + + + translations + Translations + TranslationTable + + See below + + + width + Width + Dimension + A + depends on orientation + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + + foreground + + + +A pixel value which indexes the widget's colormap to derive the color +used to draw the thumb. + + + + + + jumpProc + + + +All functions on this callback list are called when the +NotifyThumb action is invoked. See the Scrollbar +Actions section for details. + + + + + + length + + + +The height of a vertical scrollbar or the width of a horizontal scrollbar. + + + + + + minimumThumb + + + +The smallest size, in pixels, to which the thumb can shrink. + + + + + + orientation + + + +The orientation is the direction that the thumb will be allowed to move. +This value can be either XtorientVertical or +XtorientHorizontal. + + + + + + scrollDCursor + + + +This cursor is used when scrolling backward in a vertical scrollbar. + + + + + + scrollHCursor + + + +This cursor is used when a horizontal scrollbar is inactive. + + + + + + scrollLCursor + + + +This cursor is used when scrolling forward in a horizontal scrollbar. + + + + + + scrollProc + + + +All functions on this callback list may be called when the +NotifyScroll action is invoked. See the \fBScrollbar +Actions\fP section for details. + + + + + + scrollRCursor + + + +This cursor is used when scrolling backward in a horizontal scrollbar, +or when thumbing a vertical scrollbar. + + + + + + scrollUCursor + + + +This cursor is used when scrolling forward in a vertical scrollbar, or when +thumbing a horizontal scrollbar. + + + + + + scrollVCursor + + + +This cursor is used when a vertical scrollbar is inactive. + + + + + + + shown + + + +This is the size of the thumb, expressed as a percentage (0.0 - 1.0) +of the length of the scrollbar. + + + + + + thickness + + + +The width of a vertical scrollbar or the height of a horizontal scrollbar. + + + + + + thumb + + + +This pixmap is used to tile (or stipple) the thumb of the scrollbar. If +no tiling is desired, then set this resource to None. This +resource will accept either a bitmap or a pixmap that is the same depth +as the window. The resource converter for this resource constructs +bitmaps from the contents of files. (See Converting Bitmaps for +details.) + + + + + + topOfThumb + + + +The location of the top of the thumb, as a percentage (0.0 - 1.0) +of the length of the scrollbar. This resource was called top in +previous versions of the Athena widget set. The name collided with the +a Form widget constraint resource, and had to be changed. + + + + + + + + +Scrollbar Actions + + +The actions supported by the Scrollbar widget are: + + + + + StartScroll(value) + + + +The possible values are Forward, Backward, or Continuous. +This must be the first action to begin a new movement. + + + + + + NotifyScroll(value) + + + +The possible values are Proportional or FullLength. If the +argument to StartScroll was Forward or Backward, NotifyScroll executes +the scrollProc callbacks and passes either; the position of the +pointer, if value is Proportional, or the full length of the +scroll bar, if value is FullLength. If the argument to +StartScroll was Continuous, NotifyScroll returns without executing any +callbacks. + + + + + + EndScroll(\^) + + + +This must be the last action after a movement is complete. + + + + + + MoveThumb(\^) + + + +Repositions the Scrollbar's thumb to the current pointer location. + + + + + + NotifyThumb(\^)\ + + + +Calls the + +callbacks and passes the relative position of the +pointer as a percentage of the scroll bar length. + + + + + +The default bindings for Scrollbar are: + + + + + <Btn1Down>: StartScroll(Forward) + <Btn2Down>: StartScroll(Continuous) MoveThumb(\|) NotifyThumb(\|) + <Btn3Down>: StartScroll(Backward) + <Btn2Motion>: MoveThumb(\|) NotifyThumb(\|) + <BtnUp>: NotifyScroll(Proportional) EndScroll(\|) + + + +Examples of additional bindings a user might wish to specify in a +resource file are: + + + +*Scrollbar.Translations: \\ + ~Meta<Key>space: StartScroll(Forward) NotifyScroll(FullLength) \\n\\ + Meta<Key>space: StartScroll(Backward) NotifyScroll(FullLength) \\n\\ + EndScroll(\|) + + + + + +Scrollbar Callbacks + + + +There are two callback lists provided by the Scrollbar widget. +The procedural interface for these functions is described here. + + + + +The calling interface to the scrollProc callback procedure is: + + + + + void ScrollProc + Widget scrollbar + XtPointer client_data + XtPointer position + + + + + + + scrollbar + + + +Specifies the Scrollbar widget. + + + + + + client_data + + + +Specifies the client data. + + + + + + position + + + +Specifies a pixel position in integer form. + + + + + + +The scrollProc callback is used for incremental scrolling +and is called by the NotifyScroll action. +The position argument is a signed quantity and should be cast to an int +when used. Using the default button bindings, button 1 returns a +positive value, and button 3 returns a negative value. In both cases, +the magnitude of the value is the distance of the pointer in +pixels from the top (or left) of the Scrollbar. The value will never +be greater than the length of the Scrollbar. + + + +The calling interface to the jumpProc callback procedure is: + + + + + void JumpProc + Widget scrollbar + XtPointer client_data + XtPointer percent_ptr + + + + + + + + scrollbar + + + +Specifies the ID of the scroll bar widget. + + + + + + client_data + + + +Specifies the client data. + + + + + + percent_ptr + + + +Specifies the floating point position of the thumb (0.0 \- 1.0). + + + + + + +The jumpProc callback is used to implement smooth scrolling and +is called by the NotifyThumb action. Percent_ptr must be cast +to a pointer to float before use; i.e. + + + + float percent = *(float*)percent_ptr; + + + +With the default button bindings, button 2 moves the thumb interactively, +and the jumpProc is called on each new position of the pointer, +while the pointer button remains down. The value specified by +percent_ptr is the current location of the thumb (from the top or +left of the Scrollbar) expressed as a percentage of the length of the +Scrollbar. + + + + + +Convenience Routines + + +To set the position and length of a Scrollbar thumb, use + + + + + + void XawScrollbarSetThumb + Widget w + float top + float shown + + + + + + + w + + + +Specifies the Scrollbar widget. + + + + + + top + + + +Specifies the position of the top of the thumb as a fraction of the +length of the Scrollbar. + + + + + + shown + + + +Specifies the length of the thumb as a fraction of the total length +of the Scrollbar. + + + + + + +XawScrollbarThumb +moves the visible thumb to a new position (0.0 \- 1.0) and length (0.0 \- 1.0). +Either the top or shown arguments can be specified as \-1.0, +in which case the current value is left unchanged. +Values greater than 1.0 are truncated to 1.0. + + + +If called from jumpProc, has no effect. + + + + + +Setting Float Resources + + +The shown and topOfThumb resources are of type +float. These resources can be difficult to get into an +argument list. The reason is that C performs an automatic cast of +the float value to an integer value, usually truncating the important +information. The following code fragment is one portable method of +getting a float into an argument list. + + + top = 0.5; + if (sizeof(float) > sizeof(XtArgVal)) { + /* + \ * If a float is larger than an XtArgVal then pass this + \ * resource value by reference. + \ */ + XtSetArg(args[0], XtNshown, &top); + } + else { + /* + \ * Convince C not to perform an automatic conversion, which + \ * would truncate 0.5 to 0. + \ */ + XtArgVal * l_top = (XtArgVal *) &top; + XtSetArg(args[0], XtNshown, *l_top); + } + + + + diff --git a/specs/Simple.xml b/specs/Simple.xml new file mode 100644 index 0000000..0d32f74 --- /dev/null +++ b/specs/Simple.xml @@ -0,0 +1,252 @@ + +Simple Widget + + + + + + + + +Application Header file <Xaw/Simple.h> + +Class Header file <Xaw/SimpleP.h> + +Class simpleWidgetClass + +Class Name Simple + +Superclass Core + + + + +The Simple widget is not very useful by itself, as it has no semantics +of its own. It main purpose is to be used as a common superclass for +the other simple Athena widgets. This widget adds six resources +to the resource list provided by the Core widget and its superclasses. + + +Resources + + +When creating a Simple widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + NULL + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + height + Height + Dimension + + 0 + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + international + International + Boolean + C + False + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + NULL + + + width + Width + Dimension + + 0 + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/specs/SimpleMenu.xml b/specs/SimpleMenu.xml new file mode 100644 index 0000000..a99608d --- /dev/null +++ b/specs/SimpleMenu.xml @@ -0,0 +1,790 @@ + +SimpleMenu Widget + + + + + + + + +Application Header file <X11/Xaw/SimpleMenu.h> + +Class Header file <X11/Xaw/SimpleMenP.h> + +Class simpleMenuWidgetClass + +Class Name SimpleMenu + +Superclass OverrideShell + + + + +The SimpleMenu widget is a container for the menu entries. It is a +direct subclass of shell, and is should be created with +XtCreatePopupShell, not . This is the +only part of the menu that +actually is associated with a window. The SimpleMenu serves as the glue to bind +the individual menu entries together into a menu. + + +Resources + + + + + + +The resources associated with the SimpleMenu widget control aspects +that will affect the entire menu. + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + allowShellResize + AllowShellResize + Boolean + + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + backingStore + BackingStore + BackingStore + + see below + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + bottomMargin + VerticalMargins + Dimension + + 0 + + + children + ReadOnly + WidgetList + R + NULL + + + createPopupChildProc + CreatePopupChildProc + Function + + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cursor + Cursor + Cursor + + None + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + geometry + Geometry + String + + NULL + + + height + Height + Dimension + + Enough space to contain all entries + + + label + Label + String + + NULL + + + labelClass + LabelClass + Pointer + + SmeBSBObjectClass + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + menuOnScreen + MenuOnScreen + Boolean + + True + + + numChildren + ReadOnly + Cardinal + R + 0 + + + overrideRedirect + OverrideRedirect + Boolean + + True + + + popdownCallback + Callback + XtCallbackList + + NULL + + + popupCallback + Callback + XtCallbackList + + NULL + + + popupOnEntry + PopupOnEntry + Widget + A + Label or first entry + + + rowHeight + RowHeight + Dimension + + 0 + + + saveUnder + SaveUnder + Boolean + + False + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + topMargin + VerticalMargins + Dimension + + 0 + + + translations + Translations + TranslationTable + + See below + + + visual + Visual + Visual + + CopyFromParent + + + width + Width + Dimension + + Width of widest entry + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + + + backingStore + + + + +Determines what type of backing store will be used for the menu. Legal +values for this resource are NotUseful, WhenMapped, and +Always. These values are the backing-store integers defined in +<X11/X.h>. + +If default is specified (the default behavior) the server will use +whatever it thinks is appropriate. + + + + + + + + + + + bottomMargin + + + + + + + + + + + topMargin + + + +The amount of space between the top or bottom of the menu and the menu entry +closest to that edge. + + + + + + + + cursor + + + +The shape of the mouse pointer whenever it is in this widget. + + + + + + + + geometry + + + +If this resource is specified it will override the x, y, width and +height of this widget. The format of this string is +[<width>x<height>][{+ -} <xoffset> {+ -}<yoffset>]. + + + + + + + label + + + +This label will be placed at the top of the SimpleMenu, and may not be +highlighted. The name of the +label object is menuLabel. Using this name it is possible to +modify the label's attributes through the resource database. When the label +is created, the label is hard coded to the value of label, and +justify is hard coded as XtJustifyCenter. + + + + + + labelClass + + + +Specifies the type of Sme object created as the menu label. + + + + + + + menuOnScreen + + + +If the menu is automatically positioned under the cursor with the +XawPositionSimpleMenu action, and this resource is True, +then the menu will always be fully visible on the screen. + + + + + + + overrideRedirect + + + +Determines the value of the override_redirect attribute of the +SimpleMenu's window. The override_redirect attribute of a window +determines whether or not a window manager may interpose itself between +this window and the root window of the display. For more information +see the Interclient Communications Conventions Manual. + + + + + + popdownCallback + + + + + + + + + + + popupCallback + + + +These callback functions are called by the Xt Intrinsics whenever the +shell is popped up or down (See (xT for details). + + + + + + popupOnEntry + + + +The XawPositionSimpleMenu action will, by default, popup the +SimpleMenu with its label (or first entry) directly under the +pointer. To popup the menu under +another entry, set this resource to the menu entry that should be +under the pointer, when the menu is popped up. This allows the +application to offer the user a default menu entry that can be selected +with out moving the pointer. + + + + + + rowHeight + + + +If this resources is zero (the default) then each menu entry will be +given its desired height. If this resource has any other value then +all menu entries will be forced to be rowHeight pixels high. + + + + + + saveUnder + + + +If this is True then save unders will be active on the menu's window. + + + + + + + + + + + +SimpleMenu Actions + + + +The SimpleMenu widget supports the following actions: + + + + +Switching the entry under the mouse pointer between +the foreground and background colors with highlight +and unhighlight + + + + +Processing menu entry callbacks with notify + + + + + + + +The following are the default translation bindings used +by the SimpleMenu widget: + + + + + + + + <EnterWindow>: highlight(\|) + <LeaveWindow>: unhighlight(\|) + <BtnMotion>: highlight(\|) + <BtnUp>: MenuPopdown(\|) notify(\|) unhighlight(\|) + + + + + + +The user can pop down the menu without activating any of the callback +functions by releasing the pointer button when no menu item is +highlighted. + + + + +The full list of actions supported by SimpleMenu is: + + + + highlight() + + + +Highlight the menu entry that is currently under the pointer. +Only a item that is highlighted will be notified when the notify +action is invoked. The look of a highlighted entry is determined by +the menu entry. + + + + + + unhighlight(\|) + + + +Unhighlights the currently highlighted menu item, and returns it to +its normal look. + + + + + + notify(\|) + + + +Notifies the menu entry that is currently highlighted that is has been +selected. It is the responsibility of the menu entry to take the +appropriate action. + + + + + + MenuPopdown(menu) + + + +This action is defined in (xT. + + + + + + + + +Positioning the SimpleMenu + + + + +If the SimpleMenu widget is to be used as a pulldown menu then the +MenuButton widget, or some other outside means should be used to place +the menu when it is popped up. + + + +If popup menus are desired it will be necessary to add the +XawPositionSimpleMenu and MenuPopup actions to the +translation table of the widget that will be popping up the menu. The +MenuPopup action is described in (xT. +XawPositionSimpleMenu is a global action procedure registered by +the SimpleMenu widget when the first one is created or the convenience +routine is called. + + + +Translation writers should be aware that Xt does not register grabs on +``don't care'' modifiers, and therefore the left hand side of the +production should be written to exclude unspecified modifiers. +For example these are the translations needed to popup some of +xterm's menus: + + + + + + + + !Ctrl<Btn1Down>: XawPositionSimpleMenu(xterm) MenuPopup(xterm) + !Ctrl<Btn2Down>: XawPositionSimpleMenu(modes) MenuPopup(modes) + + + + + + + + + XawPositionSimpleMenu(menu) + + + +The XawPositionSimpleMenu routine will search for the menu name +passed to it using XtNameToWidget starting with the widget +invoking the action as the reference widget. If it is unsuccessful it +will continue up the widget tree using each of the invoking widget's +ancestors as the reference widget. If it is still unsuccessful it will +print a warning message and give up. XawPositionSimpleMenu will +position the menu directly under the pointer cursor. The menu will be +placed so that the pointer cursor is centered on the entry named by the +popupOnEntry resource. If the menuOnScreen resource is +True then the menu will always be fully visible on the screen. + + + + + + + +Convenience Routines + +Registering the Global Action Routines + + + +The XawPositionSimpleMenu action routine may often be invoked +before any menus have been created. This can occur when an +application uses dynamic menu creation. In these cases an application will +need to register this global action routine by calling +: + + + + void XawSimpleMenuAddGlobalActions + XtAppContext app_con + + + + + + + app_con + + + +Specifies the application context in which this action should be registered. + + + + + + + +This function need only be called once per application and must be +called before any widget that uses XawPositionSimpleMenu action +is realized. + + + +Getting and Clearing the Current Menu Entry + + +To get the currently highlighted menu entry use +: + + + + Widget XawSimpleMenuGetActiveEntry + Widget w + + + + + + + w + + + +Specifies the SimpleMenu widget. + + + + + + + +This function returns the menu entry that is +currently highlighted, or NULL if no entry is highlighted. + + + + +To clear the SimpleMenu widget's internal information about the +currently highlighted menu entry use +: + + + + Widget XawSimpleMenuClearActiveEntry + Widget w + + + + + + + w + + + +Specifies the SimpleMenu widget. + + + + + + + +This function unsets all internal references to the currently +highlighted menu entry. It does not unhighlight or otherwise +alter the appearance of the active entry. This function is primarily +for use by implementors of menu entries. + + + + + diff --git a/specs/Sme.xml b/specs/Sme.xml new file mode 100644 index 0000000..da3c4d1 --- /dev/null +++ b/specs/Sme.xml @@ -0,0 +1,207 @@ + +Sme Object + + + + + + + + + + +Application Header file <X11/Xaw/Sme.h> + +Class Header file <X11/Xaw/SmeP.h> + +Class smeObjectClass + +Class Name Sme + +Superclass RectObj + + + + + +The Sme object is the base class for all menu entries. While this +object is mainly intended to be subclassed, it may be used in a menu to +add blank space between menu entries. + + +Resources + + + +The resources associated with the SmeLine object are defined in this +section, and affect only the single menu entry specified by this object. +There are no new resources added for this class, as it picks up all its +resources from the RectObj class. + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + ancestorSensitive + AncestorSensitive + Boolean + + True + + + callback + Callback + XtCallbackList + + NULL + + + destroyCallback + Callback + XtCallbackList + + NULL + + + height + Height + Dimension + + 0 + + + international + International + Boolean + C + False + + + sensitive + Sensitive + Boolean + + True + + + width + Width + Dimension + + 1 + + + + + + + + + +Keep in mind that the SimpleMenu widget will force all menu items to +be the width of the widest entry. + + + + + +Subclassing the Sme Object + + + + +To Create a new Sme object class you will need to define three class methods. +These methods allow the SimpleMenu to highlight and unhighlight the +menu entry as the pointer cursor moves over it, as well as notify the +entry when the user has selected it. All of +these methods may be inherited from the Sme object, although the default +semantics are not very interesting. + + + + + + Highlight(\|) + + + + +Called to put the menu entry into the highlighted state. + + + + + + Unhighlight(\|) + + + + +Called to return the widget to its normal (unhighlighted) state. + + + + + + Notify(\|) + + + + +Called when the user selects this menu entry. + + + + + + + + +Other then these methods, creating a new object +is straight forward. Here is some information that may help you +avoid some common mistakes. + + + Objects can be zero pixels high. + + +Objects draw on their parent's window, therefore the Drawing dimensions +are different from those of widgets. For instance, y locations vary +from y to y + height, not 0 to height. + + + + + +XtSetValues calls may come from the application while the Sme is highlighted, +and if the SetValues method returns True, will result in an expose event. +The SimpleMenu may later call the menu entry's unhighlight +procedure. However, due to the asynchronous nature of +X, the expose event generated by will come after +this unhighlight. + + + + +Remember that your subclass of the Sme does not own the +window. Share the space with other menu entries, and refrain +from drawing outside the subclass's own section of the menu. + + + + + diff --git a/specs/SmeBSB.xml b/specs/SmeBSB.xml new file mode 100644 index 0000000..3636e2e --- /dev/null +++ b/specs/SmeBSB.xml @@ -0,0 +1,310 @@ + +SmeBSB Object + + + + + + + + + + +Application Header file <X11/Xaw/SmeBSB.h> + +Class Header file <X11/Xaw/SmeBSBP.h> + +Class smeBSBObjectClass + +Class Name SmeBSB + +Superclass Sme + + + + + +The SmeBSB object is used to create a menu entry that contains a string, +and optional bitmaps in its left and right margins. Since each menu +entry is an independent object, the application is able to change the +font, color, height, and other attributes of the menu entries, on an +entry by entry basis. The format of the string may either be the encoding +of the 8 bit font utilized, or in a multi-byte encoding for use with a +fontSet. + + +Resources + + + +The resources associated with the SmeBSB object are defined in this section, +and affect only the single menu entry specified by this object. + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + callback + Callback + Callback + + NULL + + + destroyCallback + Callback + XtCallbackList + + NULL + + + font + Font + FontStruct + + XtDefaultFont + + + fontSet + FontSet + XFontSet + + XtDefaultFontSet + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + Font height + vertSpace + + + international + International + Boolean + C + False + + + justify + Justify + Justify + + XtjustifyLeft + + + label + Label + String + + NULL + + + leftBitmap + LeftBitmap + Pixmap + + XtUnspecifiedPixmap + + + leftMargin + leftMargin + Dimension + + 4 + + + rightBitmap + RightBitmap + Pixmap + + XtUnspecifiedPixmap + + + rightMargin + rightMargin + Dimension + + 4 + + + sensitive + Sensitive + Boolean + + True + + + vertSpace + VertSpace + int + + 25 + + + width + Width + Dimension + A + TextWidth + margins + + + + + + + + + callback + + +All callback functions on this list are called when the SimpleMenu +notifies this entry that the user has selected it. + + + + + font + + +The text font to use when displaying the label, when the +international resource is false. + + + + + fontSet + + +The text font set to use when displaying the label, when the +international resource is true. + + + + + foreground + + +A pixel value which indexes the SimpleMenu's colormap to derive the +foreground color of the menu entry's window. This color is also +used to render all 1's in the left and right bitmaps. + +Keep in mind that the SimpleMenu widget will force the width of all +menu entries to be the width of the longest entry. + + + + + + justify + + + +How the label is to be rendered between the left and right margins when +the space is wider than the actual text. This resource may be +specified with the values XtJustifyLeft, XtJustifyCenter, +or XtJustifyRight. When specifying the justification from a +resource file the values left, center, or right may be +used. + + + + + label + + +This is a the string that will be displayed in the menu entry. The +exact location of this string within the bounds of the menu entry is +controlled by the leftMargin, rightMargin, vertSpace, +and justify resources. + + + + + leftBitmap + + + + + + + + + rightBitmap + + + +This is a name of a bitmap to display in the left or right margin of the +menu entry. All 1's in the bitmap will be rendered in the foreground +color, and all 0's will be drawn in the background color of the +SimpleMenu widget. It is the +programmers' responsibility to make sure that the menu entry is tall +enough, and the appropriate margin wide enough to accept the bitmap. +If care is not taken the bitmap may extend into another menu entry, or +into this entry's label. + + + + + leftMargin + + + + + + + + + rightMargin + + +This is the amount of space (in pixels) that will be left between the +edge of the menu entry and the label string. + + + + + + vertSpace + + +This is the amount of vertical padding, expressed as a percentage of +the height of the font, that is to be placed around the label of a +menu entry.. The label and bitmaps are always centered vertically +within the menu. The default value for this +resource (25) causes the default height to be 125% of the height of the +font. + + + + + + + diff --git a/specs/SmeLine.xml b/specs/SmeLine.xml new file mode 100644 index 0000000..96c920b --- /dev/null +++ b/specs/SmeLine.xml @@ -0,0 +1,148 @@ + +SmeLine Object + + + + + + + + + + +Application Header file <X11/Xaw/SmeLine.h> + +Class Header file <X11/Xaw/SmeLineP.h> + +Class smeLineObjectClass + +Class Name SmeLine + +Superclass Sme + + + + + +The SmeLine object is used to add a horizontal line or menu separator to +a menu. Since each SmeLine is an independent object, the application +is able to change the color, height, and other attributes of the SmeLine +objects on an entry by entry basis. This object is not selectable, and +will not highlight when the pointer cursor is over it. + + +Resources + + + +The resources associated with the SmeLine object are defined in this section, +and affect only the single menu entry specified by this object. + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + destroyCallback + Callback + XtCallbackList + + NULL + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + + lineWidth + + + international + International + Boolean + C + False + + + lineWidth + LineWidth + Dimension + + 1 + + + stipple + Stipple + Pixmap + + XtUnspecifiedPixmap + + + width + Width + Dimension + + 1 + + + + + + + + foreground + + +A pixel value which indexes the SimpleMenu's colormap to derive the +foreground color used to draw the separator line. + +Keep in mind that the SimpleMenu widget will force all menu items to +be the width of the widest entry. Thus, setting the width is generally not +very important. + + + + + + lineWidth + + +The width of the horizontal line that is to be displayed. + + + + + + stipple + + +If a bitmap is specified for this resource, the line will be stippled +through it. This allows the menu separator to be rendered as something +more exciting than just a line. For instance, if you define a stipple +that is a chain link, then your menu separators will look like chains. + + + + + + + diff --git a/specs/StripChart.xml b/specs/StripChart.xml new file mode 100644 index 0000000..8d5c064 --- /dev/null +++ b/specs/StripChart.xml @@ -0,0 +1,435 @@ + +StripChart Widget + + + + + + + + +Application Header file <Xaw/StripChart.h> + +Class Header file <Xaw/StripCharP.h> + +Class stripChartWidgetClass + +Class Name StripChart + +Superclass Simple + + + + +The StripChart widget is used to provide a roughly real +time graphical chart of a single value. For example, +it is used by the common client program xload +to provide a graph of processor load. The StripChart +reads data from an application, and updates the chart +at the update interval specified. + + +Resources + + +When creating a StripChart widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + NULL + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + getValue + Callback + XtCallbackList + + NULL + + + height + Height + Dimension + + 120 + + + highlight + Foreground + Pixel + + XtDefaultForeground + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + international + International + Boolean + C + False + + + jumpScroll + JumpScroll + int + A + half the width of the widget + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + minScale + Scale + int + + 1 + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + screen + Screen + Pointer + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + NULL + + + update + Interval + int + + 10 + + + width + Width + Dimension + + 120 + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + + + + + + + + + + + + + foreground + + + +A pixel value which indexes the widget's colormap to derive the color +that will be used to draw the graph. + + + + + + getValue + + + +A list of callback functions to call every update seconds. +This list should contain one function, which returns the +value to be graphed by the StripChart widget. The following +section describes the procedural interface. Behavior when this list has +more than one function is undefined. + + + + + + + highlight + + + +A pixel value which indexes the widget's colormap to derive the color +that will be used to draw the scale lines on the graph. + + + + + + + + jumpScroll + + + +When the graph reaches the right edge of the window it must be +scrolled to the left. This resource specifies the number of pixels +it will jump. Smooth scrolling can be achieved by setting this resource +to 1. + + + + + + + minScale + + + +The minimum scale for the graph. The number of divisions on the graph +will always be greater than or equal to this value. + + + + + + + + + + + update + + + +The number of seconds between graph updates. Each update is +represented on the graph as a 1 pixel wide line. Every update seconds +the getValue procedure will be used to get a new graph point, +and this point will be added to the right end of the StripChart. + + + + + + + + +Getting the StripChart Value + + + +The StripChart widget will call the application routine passed to it +as the getValue callback function every update seconds to +obtain another point for the StripChart graph. + + + +The calling interface for the getValue callback is: + + + + void(*getValueProc) + Widget w + XtPointer client_data + XtPointer value + + + + + + + w + + + +Specifies the StripChart widget. + + + + + + client_data + + + +Specifies the client data. + + + + + + value + + + +Returns a pointer to a double. The application should set the address +pointed to by this argument to a double containing the value to be +graphed on the StripChart. + + + + + + + +This function is used by the StripChart to call an application routine. +The routine will pass the value to be graphed back to the the StripChart +in the value field of this routine. + + + + diff --git a/specs/TPage_Credits.xml b/specs/TPage_Credits.xml new file mode 100644 index 0000000..bc07351 --- /dev/null +++ b/specs/TPage_Credits.xml @@ -0,0 +1,90 @@ + +Acknowledgments + + +Many thanks go to Ralph Swick (Project Athena / Digital) who has +contributed much time and effort to this widget set. Previous +versions of the widget set are largely due to his time and effort. +Many of the improvements that I have been able to make are because he +provided a solid foundation to build upon. While much of the effort +has been Ralph's, many other people have contributed to the code. + + + +Mark Ackerman (formerly Project Athena) +Donna Converse (MIT X Consortium) +Jim Fulton (formerly MIT X Consortium) +Loretta Guarino-Reid (Digital WSL) +Charles Haynes (Digital WSL) +Rich Hyde (Digital WSL) +Mary Larson (Digital UEG) +Joel McCormack (Digital WSL) +Ron Newman (formerly Project Athena) +Jeanne Rich (Digital WSL) +Terry Weissman (formerly Digital WSL) + + + +While not much remains of the X10 toolkit, many of the ideas for this +widget set come from that original version. The design and +implementation of the X10 toolkit were done by: + + + +Mike Gancarz (formerly Digital UEG) +Charles Haynes (Digital WSL) +Phil Karlton (formerly Digital WSL) +Kathleen Langone (Digital UEG) +Mary Larson (Digital UEG) +Ram Rao (Digital UEG) +Smokey Wallace (formerly Digital WSL) +Terry Weissman (formerly Digital WSL) + + + +I have used the formatting ideas, and some of the words from previous +versions of this document. The X11R3 Athena widget document was written by: + + + +Ralph R. Swick (Project Athena/ Digital) +Terry Weissman (formerly Digital WSL) +Al Mento (Digital UEG) + + + +Putting this manual together was a major task in and of itself. I +would like to thank Ralph Swick, Donna Converse, and Jim Fulton for +taking the time to help convert my technical knowledge into legible +text. A special thanks to Jean Diaz (O'Reilly and Associates) for +spending nearly a month with me working out all the annoying little +details. + + + +Chris D. Peterson +MIT X Consortium 1989 + + + +The R5 edition of this document has been edited by the research staff of +the MIT X Consortium, with significant contributions by Jim Fulton (NCD). + + + +Donna Converse +MIT X Consortium 1991 + + + +The R6 edition of this document has been edited to reflect changes +brought about by research staff of the Omron Corporation, with special +recognition to Li Yuhong, Seiji Kuwari, and Hiroshi Kuribayashi for +the X11R5/contrib/lib/Xaw internationalization that inspired this version. + + +Frank Sheeran +Omron Corporation 1994 + + + diff --git a/specs/Template.xml b/specs/Template.xml new file mode 100644 index 0000000..d9e2fc5 --- /dev/null +++ b/specs/Template.xml @@ -0,0 +1,407 @@ + +Public Header File + +The public header file contains declarations that will be required by any +application module that needs to refer to the widget; whether to create +an instance of the class, to perform an + +operation, or to call a public routine implemented by the widget class. + + + +The contents of the Template public header file, +< X11/Xaw/Template.h >, +are: + + +.. + + +/* Copyright (c) X Consortium 1987, 1988 */ + +#ifndef _Template_h +#define _Template_h + +/**************************************************************** + * + * Template widget + * + ****************************************************************/ + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + destroyCallback Callback Pointer NULL + height Height Dimension 0 + mappedWhenManaged MappedWhenManaged Boolean True + sensitive Sensitive Boolean True + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +/* define any special resource names here that are not in <X11/StringDefs.h> */ + +#define XtNtemplateResource "templateResource" + +#define XtCTemplateResource "TemplateResource" + +/* declare specific TemplateWidget class and instance datatypes */ + +typedef struct _TemplateClassRec* TemplateWidgetClass; +typedef struct _TemplateRec* TemplateWidget; + +/* declare the class constant */ + +extern WidgetClass templateWidgetClass; + +#endif /* _Template_h */ + + + + + +You will notice that most of this file is documentation. The crucial +parts are the last 8 lines where macros for any private resource names +and classes are defined and where the widget class datatypes and class +record pointer are declared. + + + +For the "WindowWidget", we want 2 drawing colors, a callback list for +user input and an +exposeCallback callback list, and we will declare three +convenience procedures, so we need to add + + + + + +/* Resources: + ... + callback Callback Callback NULL + drawingColor1 Color Pixel XtDefaultForeground + drawingColor2 Color Pixel XtDefaultForeground + exposeCallback Callback Callback NULL + font Font XFontStruct* XtDefaultFont + ... + */ + +#define XtNdrawingColor1 "drawingColor1" +#define XtNdrawingColor2 "drawingColor2" +#define XtNexposeCallback "exposeCallback" + +extern Pixel WindowColor1(\|/* Widget */\|); +extern Pixel WindowColor2(\|/* Widget */\|); +extern Font\ \ WindowFont(\|/* Widget */\|); + + + + +Note that we have chosen to call the input callback list by the generic +name, callback, rather than a specific name. If widgets that define +a single user-input action all choose the same resource name then there +is greater possibility for an application to switch between widgets of +different types. + + + +Private Header File + + +The private header file contains the complete declaration of the class +and instance structures for the widget and any additional private data +that will be required by anticipated subclasses of the widget. +Information in the private header file is normally hidden from the +application and is designed to be accessed only through other public +procedures; e.g. +XtSetValues . + + + +The contents of the Template private header file, +< X11/Xaw/TemplateP.h >, +are: + + + + +/* Copyright (c) X Consortium 1987, 1988 + */ + +#ifndef _TemplateP_h +#define _TemplateP_h + +#include <X11/Xaw/Template.h> +/* include superclass private header file */ +#include <X11/CoreP.h> + +/* define unique representation types not found in <X11/StringDefs.h> */ + +#define XtRTemplateResource "TemplateResource" + +typedef struct { + int empty; +} TemplateClassPart; + +typedef struct _TemplateClassRec { + CoreClassPart core_class; + TemplateClassPart template_class; +} TemplateClassRec; + +extern TemplateClassRec templateClassRec; + +typedef struct { + /* resources */ + char* resource; + /* private state */ +} TemplatePart; + +typedef struct _TemplateRec { + CorePart core; + TemplatePart template; +} TemplateRec; + +#endif /* _TemplateP_h */ + + + +The private header file includes the private header file of its +superclass, thereby exposing the entire internal structure of the widget. +It may not always be advantageous to do this; your own project +development style will dictate the appropriate level of detail to expose +in each module. + + +The "WindowWidget" needs to declare two fields in its instance structure to +hold the drawing colors, a resource field for the font and a field for the +expose and user input callback lists: + + + +typedef struct { + /* resources */ + Pixel color_1; + Pixel color_2; + XFontStruct* font; + XtCallbackList expose_callback; + XtCallbackList input_callback; + /* private state */ + /* (none) */ +} WindowPart; + + + + +Widget Source File + + +The source code file implements the widget class itself. The unique +part of this file is the declaration and initialization of the +widget class record structure and the declaration of all resources and +action routines added by the widget class. + + + +The contents of the Template implementation file, +< X11/Xaw/Template.c >, +are: + + + + +/* Copyright (c) X Consortium 1987, 1988 + */ + +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include "TemplateP.h" + +static XtResource resources[] = { +#define offset(field) XtOffsetOf(TemplateRec, template.field) + /* {name, class, type, size, offset, default_type, default_addr}, */ + { XtNtemplateResource, XtCTemplateResource, XtRTemplateResource, + sizeof(char*), offset(resource), XtRString, (XtPointer) "default" }, +#undef offset +}; + +static void TemplateAction(/* Widget, XEvent*, String*, Cardinal* */); + +static XtActionsRec actions[] = +{ + /* {name, procedure}, */ + {"template", TemplateAction}, +}; + +static char translations[] = +" <Key>: template(\|) \\n\\ +"; + +TemplateClassRec templateClassRec = { + { /* core fields */ + /* superclass */ (WidgetClass) &widgetClassRec, + /* class_name */ "Template", + /* widget_size */ sizeof(TemplateRec), + /* class_initialize */ NULL, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ NULL, + /* initialize_hook */ NULL, + /* realize */ XtInheritRealize, + /* actions */ actions, + /* num_actions */ XtNumber(actions), + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ TRUE, + /* compress_enterleave */ TRUE, + /* visible_interest */ FALSE, + /* destroy */ NULL, + /* resize */ NULL, + /* expose */ NULL, + /* set_values */ NULL, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ translations, + /* query_geometry */ XtInheritQueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, + { /* template fields */ + /* empty */ 0 + } +}; + +WidgetClass templateWidgetClass = (WidgetClass)&templateClassRec; + + + +The resource list for the "WindowWidget" might look like the following: + + + +static XtResource resources[] = { +#define offset(field) XtOffsetOf(WindowWidgetRec, window.field) + /* {name, class, type, size, offset, default_type, default_addr}, */ + { XtNdrawingColor1, XtCColor, XtRPixel, sizeof(Pixel), + offset(color_1), XtRString, XtDefaultForeground }, + { XtNdrawingColor2, XtCColor, XtRPixel, sizeof(Pixel), + offset(color_2), XtRString, XtDefaultForeground }, + { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct*), + offset(font), XtRString, XtDefaultFont }, + { XtNexposeCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), + offset(expose_callback), XtRCallback, NULL }, + { XtNcallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), + offset(input_callback), XtRCallback, NULL }, +#undef offset +}; + + + + +The user input callback will be implemented by an action procedure which +passes the event pointer as call_data. The action procedure +is declared as: + + + +/* ARGSUSED */ +static void InputAction(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; /* unused */ + Cardinal *num_params; /* unused */ +{ + XtCallCallbacks(w, XtNcallback, (XtPointer)event); +} + +static XtActionsRec actions[] = +{ + /* {name, procedure}, */ + {"input", InputAction}, +}; + + + + +and the default input binding will be to execute the input callbacks on +KeyPress and ButtonPress : + + +static char translations[] = +" <Key>: input(\|) \\n\\ + <BtnDown>: input(\|) \\ +"; + + + +In the class record declaration and initialization, the only field that +is different from the Template is the expose procedure: + + + +/* ARGSUSED */ +static void Redisplay(w, event, region) + Widget w; + XEvent *event; /* unused */ + Region region; +{ + XtCallCallbacks(w, XtNexposeCallback, (XtPointer)region); +} + +WindowClassRec windowClassRec = { + + ... + + /* expose */ Redisplay, + + + + + +The "WindowWidget" will also declare three public procedures to return the +drawing colors and the font id, saving the application the effort of +constructing an argument list for a call to +XtGetValues : + + + + +Pixel WindowColor1(w) + Widget w; +{ + return ((WindowWidget)w)->window.color_1; +} + +Pixel WindowColor2(w) + Widget w; +{ + return ((WindowWidget)w)->window.color_2; +} + +Font WindowFont(w) + Widget w; +{ + return ((WindowWidget)w)->window.font->fid; +} + + + +The "WindowWidget" is now complete. The application can retrieve the two +drawing colors from the widget instance by calling either +XtGetValues , +or the WindowColor functions. The actual window created for the +"WindowWidget" is available by calling the +XtWindow function. + + diff --git a/specs/Template_private_header_file.xml b/specs/Template_private_header_file.xml new file mode 100644 index 0000000..a26e92e --- /dev/null +++ b/specs/Template_private_header_file.xml @@ -0,0 +1,87 @@ + +Private Header File + + +The private header file contains the complete declaration of the class +and instance structures for the widget and any additional private data +that will be required by anticipated subclasses of the widget. +Information in the private header file is normally hidden from the +application and is designed to be accessed only through other public +procedures; e.g. +XtSetValues . + + + +The contents of the Template private header file, +< X11/Xaw/TemplateP.h >, +are: + + + + +/* Copyright (c) X Consortium 1987, 1988 + */ + +#ifndef _TemplateP_h +#define _TemplateP_h + +#include <X11/Xaw/Template.h> +/* include superclass private header file */ +#include <X11/CoreP.h> + +/* define unique representation types not found in <X11/StringDefs.h> */ + +#define XtRTemplateResource "TemplateResource" + +typedef struct { + int empty; +} TemplateClassPart; + +typedef struct _TemplateClassRec { + CoreClassPart core_class; + TemplateClassPart template_class; +} TemplateClassRec; + +extern TemplateClassRec templateClassRec; + +typedef struct { + /* resources */ + char* resource; + /* private state */ +} TemplatePart; + +typedef struct _TemplateRec { + CorePart core; + TemplatePart template; +} TemplateRec; + +#endif /* _TemplateP_h */ + + + +The private header file includes the private header file of its +superclass, thereby exposing the entire internal structure of the widget. +It may not always be advantageous to do this; your own project +development style will dictate the appropriate level of detail to expose +in each module. + + +The "WindowWidget" needs to declare two fields in its instance structure to +hold the drawing colors, a resource field for the font and a field for the +expose and user input callback lists: + + + +typedef struct { + /* resources */ + Pixel color_1; + Pixel color_2; + XFontStruct* font; + XtCallbackList expose_callback; + XtCallbackList input_callback; + /* private state */ + /* (none) */ +} WindowPart; + + + diff --git a/specs/Template_public_header_file.xml b/specs/Template_public_header_file.xml new file mode 100644 index 0000000..6e8d609 --- /dev/null +++ b/specs/Template_public_header_file.xml @@ -0,0 +1,112 @@ + +Public Header File + +The public header file contains declarations that will be required by any +application module that needs to refer to the widget; whether to create +an instance of the class, to perform an + +operation, or to call a public routine implemented by the widget class. + + + +The contents of the Template public header file, +< X11/Xaw/Template.h >, +are: + + +.. + + +/* Copyright (c) X Consortium 1987, 1988 */ + +#ifndef _Template_h +#define _Template_h + +/**************************************************************** + * + * Template widget + * + ****************************************************************/ + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + destroyCallback Callback Pointer NULL + height Height Dimension 0 + mappedWhenManaged MappedWhenManaged Boolean True + sensitive Sensitive Boolean True + width Width Dimension 0 + x Position Position 0 + y Position Position 0 + +*/ + +/* define any special resource names here that are not in <X11/StringDefs.h> */ + +#define XtNtemplateResource "templateResource" + +#define XtCTemplateResource "TemplateResource" + +/* declare specific TemplateWidget class and instance datatypes */ + +typedef struct _TemplateClassRec* TemplateWidgetClass; +typedef struct _TemplateRec* TemplateWidget; + +/* declare the class constant */ + +extern WidgetClass templateWidgetClass; + +#endif /* _Template_h */ + + + + + +You will notice that most of this file is documentation. The crucial +parts are the last 8 lines where macros for any private resource names +and classes are defined and where the widget class datatypes and class +record pointer are declared. + + + +For the "WindowWidget", we want 2 drawing colors, a callback list for +user input and an +exposeCallback callback list, and we will declare three +convenience procedures, so we need to add + + + + + +/* Resources: + ... + callback Callback Callback NULL + drawingColor1 Color Pixel XtDefaultForeground + drawingColor2 Color Pixel XtDefaultForeground + exposeCallback Callback Callback NULL + font Font XFontStruct* XtDefaultFont + ... + */ + +#define XtNdrawingColor1 "drawingColor1" +#define XtNdrawingColor2 "drawingColor2" +#define XtNexposeCallback "exposeCallback" + +extern Pixel WindowColor1(\|/* Widget */\|); +extern Pixel WindowColor2(\|/* Widget */\|); +extern Font\ \ WindowFont(\|/* Widget */\|); + + + + +Note that we have chosen to call the input callback list by the generic +name, callback, rather than a specific name. If widgets that define +a single user-input action all choose the same resource name then there +is greater possibility for an application to switch between widgets of +different types. + + diff --git a/specs/Template_widget_source_file.xml b/specs/Template_widget_source_file.xml new file mode 100644 index 0000000..62ad1b6 --- /dev/null +++ b/specs/Template_widget_source_file.xml @@ -0,0 +1,208 @@ + +Widget Source File + + +The source code file implements the widget class itself. The unique +part of this file is the declaration and initialization of the +widget class record structure and the declaration of all resources and +action routines added by the widget class. + + + +The contents of the Template implementation file, +< X11/Xaw/Template.c >, +are: + + + + +/* Copyright (c) X Consortium 1987, 1988 + */ + +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include "TemplateP.h" + +static XtResource resources[] = { +#define offset(field) XtOffsetOf(TemplateRec, template.field) + /* {name, class, type, size, offset, default_type, default_addr}, */ + { XtNtemplateResource, XtCTemplateResource, XtRTemplateResource, + sizeof(char*), offset(resource), XtRString, (XtPointer) "default" }, +#undef offset +}; + +static void TemplateAction(/* Widget, XEvent*, String*, Cardinal* */); + +static XtActionsRec actions[] = +{ + /* {name, procedure}, */ + {"template", TemplateAction}, +}; + +static char translations[] = +" <Key>: template(\|) \\n\\ +"; + +TemplateClassRec templateClassRec = { + { /* core fields */ + /* superclass */ (WidgetClass) &widgetClassRec, + /* class_name */ "Template", + /* widget_size */ sizeof(TemplateRec), + /* class_initialize */ NULL, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ NULL, + /* initialize_hook */ NULL, + /* realize */ XtInheritRealize, + /* actions */ actions, + /* num_actions */ XtNumber(actions), + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ TRUE, + /* compress_enterleave */ TRUE, + /* visible_interest */ FALSE, + /* destroy */ NULL, + /* resize */ NULL, + /* expose */ NULL, + /* set_values */ NULL, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ translations, + /* query_geometry */ XtInheritQueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, + { /* template fields */ + /* empty */ 0 + } +}; + +WidgetClass templateWidgetClass = (WidgetClass)&templateClassRec; + + + +The resource list for the "WindowWidget" might look like the following: + + + +static XtResource resources[] = { +#define offset(field) XtOffsetOf(WindowWidgetRec, window.field) + /* {name, class, type, size, offset, default_type, default_addr}, */ + { XtNdrawingColor1, XtCColor, XtRPixel, sizeof(Pixel), + offset(color_1), XtRString, XtDefaultForeground }, + { XtNdrawingColor2, XtCColor, XtRPixel, sizeof(Pixel), + offset(color_2), XtRString, XtDefaultForeground }, + { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct*), + offset(font), XtRString, XtDefaultFont }, + { XtNexposeCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), + offset(expose_callback), XtRCallback, NULL }, + { XtNcallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), + offset(input_callback), XtRCallback, NULL }, +#undef offset +}; + + + + +The user input callback will be implemented by an action procedure which +passes the event pointer as call_data. The action procedure +is declared as: + + + +/* ARGSUSED */ +static void InputAction(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; /* unused */ + Cardinal *num_params; /* unused */ +{ + XtCallCallbacks(w, XtNcallback, (XtPointer)event); +} + +static XtActionsRec actions[] = +{ + /* {name, procedure}, */ + {"input", InputAction}, +}; + + + + +and the default input binding will be to execute the input callbacks on +KeyPress and ButtonPress : + + +static char translations[] = +" <Key>: input(\|) \\n\\ + <BtnDown>: input(\|) \\ +"; + + + +In the class record declaration and initialization, the only field that +is different from the Template is the expose procedure: + + + +/* ARGSUSED */ +static void Redisplay(w, event, region) + Widget w; + XEvent *event; /* unused */ + Region region; +{ + XtCallCallbacks(w, XtNexposeCallback, (XtPointer)region); +} + +WindowClassRec windowClassRec = { + + ... + + /* expose */ Redisplay, + + + + + +The "WindowWidget" will also declare three public procedures to return the +drawing colors and the font id, saving the application the effort of +constructing an argument list for a call to +XtGetValues : + + + + +Pixel WindowColor1(w) + Widget w; +{ + return ((WindowWidget)w)->window.color_1; +} + +Pixel WindowColor2(w) + Widget w; +{ + return ((WindowWidget)w)->window.color_2; +} + +Font WindowFont(w) + Widget w; +{ + return ((WindowWidget)w)->window.font->fid; +} + + + +The "WindowWidget" is now complete. The application can retrieve the two +drawing colors from the widget instance by calling either +XtGetValues , +or the WindowColor functions. The actual window created for the +"WindowWidget" is available by calling the +XtWindow function. + + diff --git a/specs/Text.xml b/specs/Text.xml new file mode 100644 index 0000000..d2d5e30 --- /dev/null +++ b/specs/Text.xml @@ -0,0 +1,326 @@ + +Text Widget + + +Application Header file <X11/Xaw/Text.h> +Class Header file <X11/Xaw/TextP.h> +Class textWidgetClass +Class Name Text +Superclass Simple + + + + +The Text widget is the glue that binds all the other pieces together, it +maintains the internal state of the displayed text, and acts as a +mediator between the source and sink. + + + +This section lists the resources that are actually part of the +Text widget, and explains the functionality provided by each. + + +Resources + + +When creating a Text widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + autoFill + AutoFill + Boolean + + False + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + bottomMargin + Margin + Position + + 2 + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cursor + Cursor + Cursor + + XC_xterm + + + cursorName + Cursor + String + + NULL + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + displayCaret + Output + Boolean + + True + + + displayPosition + TextPosition + XawTextPosition + + 0 + + + height + Height + Dimension + A + Font height + margins + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + insertPosition + TextPosition + int + + 0 + + + leftMargin + Margin + Position + + 2 + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + resize + Resize + XawTextResizeMode + + XawtextResizeNever + + + rightMargin + Margin + Position + + 4 + + + screen + Screen + Pointer + R + Parent's Screen + + + scrollHorizontal + Scroll + ScrollMode + + XawtextScrollNever + + + scrollVertical + Scroll + XawTextScrollMode + + XawtextScrollNever + + + selectTypes + SelectTypes + XawTextSelectType* + + See above + + + sensitive + Sensitive + Boolean + + True + + + textSink + TextSink + Widget + + NULL + + + textSource + TextSource + Widget + + NULL + + + topMargin + Margin + Position + + 2 + + + translations + Translations + TranslationTable + + See above + + + unrealizeCallback + Callback + XtCallbackList + + NULL + + + width + Width + Dimension + + 100 + + + wrap + Wrap + WrapMode + + XawtextWrapNever + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + diff --git a/specs/TextActions.xml b/specs/TextActions.xml new file mode 100644 index 0000000..0e54582 --- /dev/null +++ b/specs/TextActions.xml @@ -0,0 +1,976 @@ + +Text Widget Actions + + + + + + + + +All editing functions are performed by translation manager actions that may +be specified through the translations resource in the Text widget. + + + + + + + +Insert Point Movement Delete + forward-character delete-next-character + backward-character delete-previous-character + forward-word delete-next-word + backward-word delete-previous-word + forward-paragraph delete-selection + backward-paragraph + beginning-of-line + end-of-line Selection + next-line select-word + previous-line select-all + next-page select-start + previous-page select-adjust + beginning-of-file select-end + end-of-file extend-start + scroll-one-line-up extend-adjust + scroll-one-line-down extend-end + insert-selection + + +Miscellaneous New Line + redraw-display newline-and-indent + insert-file newline-and-backup + insert-char newline + insert-string + display-caret + focus-in Kill + focus-in kill-word + search backward-kill-word + multiply kill-selection + form-paragraph kill-to-end-of-line + transpose-characters kill-paragraph + no-op kill-to-end-of-paragraph + XawWMProtocols + reconnect-im + + + + + +Most of the actions take no arguments, and unless otherwise noted you +may assume this to be the case. + + + + + +Cursor Movement Actions\fP + + + + + + + forward-character() + + + + + + + + + + + backward-character() + + + +These actions move the insert point forward or backward one character in +the buffer. If the insert point is at the end or beginning of a line +this action will move the insert point to the next (or previous) line. + + + + + + forward-word() + + + + + + + + + + + backward-word() + + + +These actions move the insert point to the next or previous word boundary. +A word boundary is defined as a Space, Tab or Carriage Return. + + + + + + forward-paragraph() + + + + + + + + + + + backward-paragraph() + + + +These actions move the insert point to the next or previous paragraph boundary. +A paragraph boundary is defined as two Carriage Returns in a row with only +Spaces or Tabs between them. + + + + + + beginning-of-line() + + + + + + + + + + + end-of-line() + + + +These actions move to the beginning or end of the current line. If the +insert point is already at the end or beginning of the line then no action is taken. + + + + + + next-line() + + + + + + + + + + + previous-line() + + + +These actions move the insert point up or down one line. If the insert +point is currently N characters from the beginning of the line then it +will be N characters from the beginning of the next or previous line. +If N is past the end of the line, the insert point is placed at the end +of the line. + + + + + + next-page() + + + + + + + + + + + previous-page() + + + +These actions move the insert point up or down one page in the file. +One page is defined as the current height of the text widget. The +insert point is always placed at the first character of the top line by +this action. + + + + + + beginning-of-file() + + + + + + + + + + + end-of-file() + + + +These actions place the insert point at the beginning or end of the +current text buffer. The text widget is then scrolled the minimum +amount necessary to make the new insert point location visible. + + + + + + scroll-one-line-up() + + + + + + + + + + + scroll-one-line-down() + + + +These actions scroll the current text field up or down by one line. +They do not move the insert point. Other than the scrollbars this is +the only way that the insert point may be moved off of the visible text +area. The widget will be scrolled so that the insert point is back on +the screen as soon as some other action is executed. + + + + + + + +Delete Actions + + + + + + + delete-next-character() + + + + + + + + + + + delete-previous-character() + + + +These actions remove the character immediately before or after the +insert point. If a Carriage Return is removed then the next line is +appended to the end of the current line. + + + + + + delete-next-word() + + + + + + + + + + + delete-previous-word() + + + +These actions remove all characters between the insert point location and +the next word boundary. A word boundary is defined as a Space, Tab or +Carriage Return. + + + + + + delete-selection() + + + +This action removes all characters in the current selection. +The selection can be set with the selection actions. + + + + + + + +Selection Actions + + + + + + + select-word() + + + +This action selects the word in which the insert point is currently located. +If the insert point is between words then it will select the previous word. + + + + + + select-all() + + + +This action selects the entire text buffer. + + + + + + select-start() + + + +This action sets the insert point to the current pointer location (if +triggered by a button event) or text cursor location (if triggered by +a key event). It +will then begin a selection at this location. If many of these +selection actions occur quickly in succession then the selection count +mechanism will be invoked (see the section titled \fBText Selections for +Application Programmers\fP for details). + + + + + + select-adjust() + + + +This action allows a selection started with the select-start +action to be modified, as described above. + + + + + + select-end(name[,name,...]) + + + +This action ends a text selection that began with the select-start +action, and asserts ownership of the selection or selections specified. +A name can be a selection (e.g., PRIMARY) or a cut buffer +(e.g., CUT_BUFFER0). Note that case is important. If no +names are specified, PRIMARY is asserted. + + + + + + extend-start() + + + +This action finds the nearest end of the current selection, and moves it +to the current pointer location (if triggered by a button event) or text +cursor location (if triggered by a key event). + + + + + + extend-adjust() + + + +This action allows a selection started with an extend-start action +to be modified. + + + + + + extend-end(name[,name,...]) + + + +This action ends a text selection that began with the extend-start +action, and asserts ownership of the selection or selections specified. +A name can be a selection (e.g. PRIMARY) or a cut buffer +(e.g CUT_BUFFER0). Note that case is important. If no names are +given, PRIMARY is asserted. + + + + + + insert-selection(name[,name,...]) + + + +This action retrieves the value of the first (left-most) named selection +that exists or the cut buffer that is not empty and inserts it into the +Text widget at the current insert point location. A name can be a +selection (e.g. PRIMARY) or a cut buffer (e.g CUT_BUFFER0). +Note that case is important. + + + + + + + +The New Line Actions + + + + + + + newline-and-indent() + + + +This action inserts a newline into the text and adds spaces to +that line to indent it to match the previous line. + + + + + + newline-and-backup() + + + +This action inserts a newline into the text after the insert point. + + + + + + newline() + + + +This action inserts a newline into the text before the insert point. + + + + + + + +Kill and Actions + + + + + + + kill-word() + + + + + + + + + + + backward-kill-word() + + + +These actions act exactly like the delete-next-word and +delete-previous-word actions, but they stuff the word that was +killed into the kill buffer (CUT_BUFFER_1). + + + + + + kill-selection() + + + +This action deletes the current selection and stuffs the deleted text into +the kill buffer (CUT_BUFFER_1). + + + + + + kill-to-end-of-line() + + + +This action deletes the entire line to the right of the insert point position, +and stuffs the deleted text into the kill buffer (CUT_BUFFER_1). + + + + + + kill-paragraph() + + + +This action deletes the current paragraph, if between paragraphs it deletes +the paragraph above the insert point, and stuffs the deleted text into +the kill buffer (CUT_BUFFER_1). + + + + + + kill-to-end-of-paragraph() + + + +This action deletes everything between the current insert point location and +the next paragraph boundary, and stuffs the deleted text into the kill +buffer (CUT_BUFFER_1). + + + + + + + +Miscellaneous Actions + + + + + + + redraw-display() + + + +This action recomputes the location of all the text lines on the +display, scrolls the text to vertically center the line containing the insert point +on the screen, clears the entire screen, and redisplays it. + + + + + + insert-file([filename]) + + + +This action activates the insert file popup. The filename +option specifies the default filename to put in the filename buffer of +the popup. If no filename is specified the buffer is empty +at startup. + + + + + + insert-char() + + + +This action may only be attached to a key event. When the +international resource is false, this action +calls XLookupString to translate the event into a (rebindable) Latin-1 +character (sequence) and inserts it into the text at the +insert point. When the international resource is true, +characters are passed to the input method via XwcLookupString, and any +committed string returned is inserted into the text at the insert point. + + + + + + insert-string(string[,string,...]) + + + +This action inserts each string into the text +at the insert point location. Any string +beginning with the characters "0x" followed by an even +number of hexadecimal digits is +interpreted as a hexadecimal constant and the +corresponding string is inserted instead. This +hexadecimal string may represent up to 50 8-bit characters. + When theinternational resource is +true, a hexadecimal string is intrepeted as +being in a multi-byte encoding, and a hexadecimal +or regular string will result in an error message +if it is not legal in the current locale. + + + + + + display-caret(state,when) + + + +This action allows the insert point to be turned on and off. +The state argument specifies the desired state of the insert point. +This value may be any of the string +values accepted for Boolean resources (e.g. on, True, +off, False, etc.). If no arguments are specified, the +default value is True. +The when argument specifies, for EnterNotify or LeaveNotify +events whether or not the focus field in the event is to be examined. +If the second argument is not specified, or specified as something other +than always then if the action is bound to an EnterNotify +or LeaveNotify event, the action will be taken only if the focus +field is True. An augmented binding that might be useful is: + + + + + + + + + + + *Text.Translations: #override \\ + <FocusIn>: display-caret(on) \\n\\ + <FocusOut>: display-caret(off) + + + + + focus-in() + + + + + + + + + + + focus-out() + + + +These actions do not currently do anything. + + + + + + search(direction,[string]) + + + +This action activates the search popup. The direction must be +specified as either forward or backward. The string is +optional and is used as an initial value for the Search for: string. +For further explanation of the search widget see the section on +Text Searches. + + + + + + multiply(value) + + + +The multiply action allows the user to multiply the effects of many of +the text actions. Thus the following action sequence +multiply(10) delete-next-word() will delete 10 words. It does not +matter whether these actions take place in one event or many events. +Using the default translations the key sequence \fIControl-u, +Control-d\fP will delete 4 characters. +Multiply actions can be chained, thus \fImultiply(5) +multiply(5)\fP is the same as multiply(25). If the string +reset is passed to the multiply action the effects of all previous +multiplies are removed and a beep is sent to the display. + + + + + + form-paragraph() + + + +This action removes all the Carriage Returns from the current +paragraph and reinserts them so that each line is as long as possible, while +still fitting on the current screen. Lines are broken at word boundaries if +at all possible. This action currently works only on Text widgets +that use ASCII text. + + + + + + transpose-characters() + + + +This action will swap the position of the character to the left of the +insert point with the character to the right of the insert point. The insert point will then +be advanced one character. + + + + + + no-op([action]) + + + +The no-op action makes no change to the text widget, and is mainly used +to override translations. This action takes one optional argument. If +this argument is RingBell then a beep is sent to the display. + + + + + + XawWMProtocols([wm_protocol_name]) + + + + + +This action is written specifically for the file insertion and the search +and replace +dialog boxes. This action is attached to those shells by the Text widget, +in order to handle ClientMessage events with the WM_PROTOCOLS atom in the +detail field. This action supports WM_DELETE_WINDOW on the Text widget +popups, and may support other window manager protocols if necessary in +the future. The popup will be dismissed if the window manager sends +a WM_DELETE_WINDOW request and there are no parameters in the action +call, which is the default. The popup will also be dismissed if the +parameters include the string ``wm_delete_window,'' and the event is a +ClientMessage event requesting dismissal or is not a ClientMessage event. +This action is not sensitive to the case of the strings passed as parameters. + + + + + + reconnect-im() + + + + +When the international resource is true, +input is usually passed to an input method, a separate +process, for composing. Sometimes the connection to +this process gets severed; this action will attempt to +reconnect it. Causes for severage include network +trouble, and the user explicitly killing one input +method and starting a new one. This action may also +establish first connection when the application is +started before the input method. + + + + + + + +Text Selections for Application Programmers + + + +The default behavior of the text selection array is described in the +section called Text Selections for Users. To modify the selections +a programmer must construct a XawTextSelectType array (called the +selection array), containing the selections desired, and pass this as +the new value for the selectionTypes resource. The selection +array may also be modified using the + +function. All selection arrays must end with the value +XawselectNull. The selectionTypes resource has no converter +registered and cannot be modified through the resource manager. + + + +The array contains a list of entries that will be called when the user +attempts to select text in rapid succession with the select-start +action (usually by clicking a pointer button). The first entry in the +selection array will be used when the select-start action is +initially called. The next entry will be used when select-start +is called again, and so on. If a timeout value (1/10 of a second) is +exceeded, the the next select-start action will begin at the top +of the selection array. When XawselectNull is reached the array +is recycled beginning with the first element. + + + + + + + + XawselectAll + Selects the contents of the entire buffer. + + + XawselectChar + Selects text characters as the pointer moves over them. + + + XawselectLine + Selects the entire line. + + + XawselectNull + Indicates the end of the selection array. + + + XawselectParagraph + Selects the entire paragraph. + + + XawselectPosition + Selects the current pointer position. + + + XawselectWord + Selects whole words as the pointer moves onto them. + + + + + + + +The default selectType array is: + + + + + +{XawselectPosition, XawselectWord, XawselectLine, XawselectParagraph, XawselectAll, XawselectNull} + + + + + +The selection array is not copied by the text widgets. The +application must allocate space for the array and cannot deallocate or +change it until the text widget is destroyed or until a new selection +array is set. + + + + +Default Translation Bindings + + + + + + +The following translations are defaults built into every Text widget. +They can be overridden, or replaced by specifying a new value for the +Text widget's translations resource. + + + + + + + + Ctrl<Key>A: beginning-of-line() \\n\\ + Ctrl<Key>B: backward-character() \\n\\ + Ctrl<Key>D: delete-next-character() \\n\\ + Ctrl<Key>E: end-of-line() \\n\\ + Ctrl<Key>F: forward-character() \\n\\ + Ctrl<Key>G: multiply(Reset) \\n\\ + Ctrl<Key>H: delete-previous-character() \\n\\ + Ctrl<Key>J: newline-and-indent() \\n\\ + Ctrl<Key>K: kill-to-end-of-line() \\n\\ + Ctrl<Key>L: redraw-display() \\n\\ + Ctrl<Key>M: newline() \\n\\ + Ctrl<Key>N: next-line() \\n\\ + Ctrl<Key>O: newline-and-backup() \\n\\ + Ctrl<Key>P: previous-line() \\n\\ + Ctrl<Key>R: search(backward) \\n\\ + Ctrl<Key>S: search(forward) \\n\\ + Ctrl<Key>T: transpose-characters() \\n\\ + Ctrl<Key>U: multiply(4) \\n\\ + Ctrl<Key>V: next-page() \\n\\ + Ctrl<Key>W: kill-selection() \\n\\ + Ctrl<Key>Y: insert-selection(CUT_BUFFER1) \\n\\ + Ctrl<Key>Z: scroll-one-line-up() \\n\\ + Ctrl<Key>\\: reconnect-im() \\n\\ + Meta<Key>B: backward-word() \\n\\ + Meta<Key>F: forward-word() \\n\\ + Meta<Key>I: insert-file() \\n\\ + Meta<Key>K: kill-to-end-of-paragraph() \\n\\ + Meta<Key>Q: form-paragraph() \\n\\ + Meta<Key>V: previous-page() \\n\\ + Meta<Key>Y: insert-selection(PRIMARY, CUT_BUFFER0) \\n\\ + Meta<Key>Z: scroll-one-line-down() \\n\\ + :Meta<Key>d: delete-next-word() \\n\\ + :Meta<Key>D: kill-word() \\n\\ + :Meta<Key>h: delete-previous-word() \\n\\ + :Meta<Key>H: backward-kill-word() \\n\\ + :Meta<Key>\\<: beginning-of-file() \\n\\ + :Meta<Key>\\>: end-of-file() \\n\\ + :Meta<Key>]: forward-paragraph() \\n\\ + :Meta<Key>[: backward-paragraph() \\n\\ + ~Shift Meta<Key>Delete: delete-previous-word() \\n\\ + \ Shift Meta<Key>Delete: backward-kill-word() \\n\\ + ~Shift Meta<Key>Backspace: delete-previous-word() \\n\\ + \ Shift Meta<Key>Backspace: backward-kill-word() \\n\\ + <Key>Right: forward-character() \\n\\ + <Key>Left: backward-character() \\n\\ + <Key>Down: next-line() \\n\\ + <Key>Up: previous-line() \\n\\ + <Key>Delete: delete-previous-character() \\n\\ + <Key>BackSpace: delete-previous-character() \\n\\ + <Key>Linefeed: newline-and-indent() \\n\\ + <Key>Return: newline() \\n\\ + <Key>: insert-char() \\n\\ + <Key>Kanji: reconnect-im() \\n\\ + <FocusIn>: focus-in() \\n\\ + <FocusOut>: focus-out() \\n\\ + <Btn1Down>: select-start() \\n\\ + <Btn1Motion>: extend-adjust() \\n\\ + <Btn1Up>: extend-end(PRIMARY, CUT_BUFFER0) \\n\\ + <Btn2Down>: insert-selection(PRIMARY, CUT_BUFFER0) \\n\\ + <Btn3Down>: extend-start() \\n\\ + <Btn3Motion>: extend-adjust() \\n\\ + <Btn3Up>: extend-end(PRIMARY, CUT_BUFFER0) \\n + + + + + diff --git a/specs/TextActions_default_translation_bindings.xml b/specs/TextActions_default_translation_bindings.xml new file mode 100644 index 0000000..7318811 --- /dev/null +++ b/specs/TextActions_default_translation_bindings.xml @@ -0,0 +1,85 @@ + +Default Translation Bindings + + + + + + +The following translations are defaults built into every Text widget. +They can be overridden, or replaced by specifying a new value for the +Text widget's translations resource. + + + + + + + + Ctrl<Key>A: beginning-of-line() \\n\\ + Ctrl<Key>B: backward-character() \\n\\ + Ctrl<Key>D: delete-next-character() \\n\\ + Ctrl<Key>E: end-of-line() \\n\\ + Ctrl<Key>F: forward-character() \\n\\ + Ctrl<Key>G: multiply(Reset) \\n\\ + Ctrl<Key>H: delete-previous-character() \\n\\ + Ctrl<Key>J: newline-and-indent() \\n\\ + Ctrl<Key>K: kill-to-end-of-line() \\n\\ + Ctrl<Key>L: redraw-display() \\n\\ + Ctrl<Key>M: newline() \\n\\ + Ctrl<Key>N: next-line() \\n\\ + Ctrl<Key>O: newline-and-backup() \\n\\ + Ctrl<Key>P: previous-line() \\n\\ + Ctrl<Key>R: search(backward) \\n\\ + Ctrl<Key>S: search(forward) \\n\\ + Ctrl<Key>T: transpose-characters() \\n\\ + Ctrl<Key>U: multiply(4) \\n\\ + Ctrl<Key>V: next-page() \\n\\ + Ctrl<Key>W: kill-selection() \\n\\ + Ctrl<Key>Y: insert-selection(CUT_BUFFER1) \\n\\ + Ctrl<Key>Z: scroll-one-line-up() \\n\\ + Ctrl<Key>\\: reconnect-im() \\n\\ + Meta<Key>B: backward-word() \\n\\ + Meta<Key>F: forward-word() \\n\\ + Meta<Key>I: insert-file() \\n\\ + Meta<Key>K: kill-to-end-of-paragraph() \\n\\ + Meta<Key>Q: form-paragraph() \\n\\ + Meta<Key>V: previous-page() \\n\\ + Meta<Key>Y: insert-selection(PRIMARY, CUT_BUFFER0) \\n\\ + Meta<Key>Z: scroll-one-line-down() \\n\\ + :Meta<Key>d: delete-next-word() \\n\\ + :Meta<Key>D: kill-word() \\n\\ + :Meta<Key>h: delete-previous-word() \\n\\ + :Meta<Key>H: backward-kill-word() \\n\\ + :Meta<Key>\\<: beginning-of-file() \\n\\ + :Meta<Key>\\>: end-of-file() \\n\\ + :Meta<Key>]: forward-paragraph() \\n\\ + :Meta<Key>[: backward-paragraph() \\n\\ + ~Shift Meta<Key>Delete: delete-previous-word() \\n\\ + \ Shift Meta<Key>Delete: backward-kill-word() \\n\\ + ~Shift Meta<Key>Backspace: delete-previous-word() \\n\\ + \ Shift Meta<Key>Backspace: backward-kill-word() \\n\\ + <Key>Right: forward-character() \\n\\ + <Key>Left: backward-character() \\n\\ + <Key>Down: next-line() \\n\\ + <Key>Up: previous-line() \\n\\ + <Key>Delete: delete-previous-character() \\n\\ + <Key>BackSpace: delete-previous-character() \\n\\ + <Key>Linefeed: newline-and-indent() \\n\\ + <Key>Return: newline() \\n\\ + <Key>: insert-char() \\n\\ + <Key>Kanji: reconnect-im() \\n\\ + <FocusIn>: focus-in() \\n\\ + <FocusOut>: focus-out() \\n\\ + <Btn1Down>: select-start() \\n\\ + <Btn1Motion>: extend-adjust() \\n\\ + <Btn1Up>: extend-end(PRIMARY, CUT_BUFFER0) \\n\\ + <Btn2Down>: insert-selection(PRIMARY, CUT_BUFFER0) \\n\\ + <Btn3Down>: extend-start() \\n\\ + <Btn3Motion>: extend-adjust() \\n\\ + <Btn3Up>: extend-end(PRIMARY, CUT_BUFFER0) \\n + + + + + diff --git a/specs/TextActions_text_widget_actions.xml b/specs/TextActions_text_widget_actions.xml new file mode 100644 index 0000000..af77052 --- /dev/null +++ b/specs/TextActions_text_widget_actions.xml @@ -0,0 +1,891 @@ + +Text Widget Actions + + + + + + + + +All editing functions are performed by translation manager actions that may +be specified through the translations resource in the Text widget. + + + + + + + +Insert Point Movement Delete + forward-character delete-next-character + backward-character delete-previous-character + forward-word delete-next-word + backward-word delete-previous-word + forward-paragraph delete-selection + backward-paragraph + beginning-of-line + end-of-line Selection + next-line select-word + previous-line select-all + next-page select-start + previous-page select-adjust + beginning-of-file select-end + end-of-file extend-start + scroll-one-line-up extend-adjust + scroll-one-line-down extend-end + insert-selection + + +Miscellaneous New Line + redraw-display newline-and-indent + insert-file newline-and-backup + insert-char newline + insert-string + display-caret + focus-in Kill + focus-in kill-word + search backward-kill-word + multiply kill-selection + form-paragraph kill-to-end-of-line + transpose-characters kill-paragraph + no-op kill-to-end-of-paragraph + XawWMProtocols + reconnect-im + + + + + +Most of the actions take no arguments, and unless otherwise noted you +may assume this to be the case. + + + + + +Cursor Movement Actions\fP + + + + + + + forward-character() + + + + + + + + + + + backward-character() + + + +These actions move the insert point forward or backward one character in +the buffer. If the insert point is at the end or beginning of a line +this action will move the insert point to the next (or previous) line. + + + + + + forward-word() + + + + + + + + + + + backward-word() + + + +These actions move the insert point to the next or previous word boundary. +A word boundary is defined as a Space, Tab or Carriage Return. + + + + + + forward-paragraph() + + + + + + + + + + + backward-paragraph() + + + +These actions move the insert point to the next or previous paragraph boundary. +A paragraph boundary is defined as two Carriage Returns in a row with only +Spaces or Tabs between them. + + + + + + beginning-of-line() + + + + + + + + + + + end-of-line() + + + +These actions move to the beginning or end of the current line. If the +insert point is already at the end or beginning of the line then no action is taken. + + + + + + next-line() + + + + + + + + + + + previous-line() + + + +These actions move the insert point up or down one line. If the insert +point is currently N characters from the beginning of the line then it +will be N characters from the beginning of the next or previous line. +If N is past the end of the line, the insert point is placed at the end +of the line. + + + + + + next-page() + + + + + + + + + + + previous-page() + + + +These actions move the insert point up or down one page in the file. +One page is defined as the current height of the text widget. The +insert point is always placed at the first character of the top line by +this action. + + + + + + beginning-of-file() + + + + + + + + + + + end-of-file() + + + +These actions place the insert point at the beginning or end of the +current text buffer. The text widget is then scrolled the minimum +amount necessary to make the new insert point location visible. + + + + + + scroll-one-line-up() + + + + + + + + + + + scroll-one-line-down() + + + +These actions scroll the current text field up or down by one line. +They do not move the insert point. Other than the scrollbars this is +the only way that the insert point may be moved off of the visible text +area. The widget will be scrolled so that the insert point is back on +the screen as soon as some other action is executed. + + + + + + + +Delete Actions + + + + + + + delete-next-character() + + + + + + + + + + + delete-previous-character() + + + +These actions remove the character immediately before or after the +insert point. If a Carriage Return is removed then the next line is +appended to the end of the current line. + + + + + + delete-next-word() + + + + + + + + + + + delete-previous-word() + + + +These actions remove all characters between the insert point location and +the next word boundary. A word boundary is defined as a Space, Tab or +Carriage Return. + + + + + + delete-selection() + + + +This action removes all characters in the current selection. +The selection can be set with the selection actions. + + + + + + + +Selection Actions + + + + + + + select-word() + + + +This action selects the word in which the insert point is currently located. +If the insert point is between words then it will select the previous word. + + + + + + select-all() + + + +This action selects the entire text buffer. + + + + + + select-start() + + + +This action sets the insert point to the current pointer location (if +triggered by a button event) or text cursor location (if triggered by +a key event). It +will then begin a selection at this location. If many of these +selection actions occur quickly in succession then the selection count +mechanism will be invoked (see the section titled \fBText Selections for +Application Programmers\fP for details). + + + + + + select-adjust() + + + +This action allows a selection started with the select-start +action to be modified, as described above. + + + + + + select-end(name[,name,...]) + + + +This action ends a text selection that began with the select-start +action, and asserts ownership of the selection or selections specified. +A name can be a selection (e.g., PRIMARY) or a cut buffer +(e.g., CUT_BUFFER0). Note that case is important. If no +names are specified, PRIMARY is asserted. + + + + + + extend-start() + + + +This action finds the nearest end of the current selection, and moves it +to the current pointer location (if triggered by a button event) or text +cursor location (if triggered by a key event). + + + + + + extend-adjust() + + + +This action allows a selection started with an extend-start action +to be modified. + + + + + + extend-end(name[,name,...]) + + + +This action ends a text selection that began with the extend-start +action, and asserts ownership of the selection or selections specified. +A name can be a selection (e.g. PRIMARY) or a cut buffer +(e.g CUT_BUFFER0). Note that case is important. If no names are +given, PRIMARY is asserted. + + + + + + insert-selection(name[,name,...]) + + + +This action retrieves the value of the first (left-most) named selection +that exists or the cut buffer that is not empty and inserts it into the +Text widget at the current insert point location. A name can be a +selection (e.g. PRIMARY) or a cut buffer (e.g CUT_BUFFER0). +Note that case is important. + + + + + + + +The New Line Actions + + + + + + + newline-and-indent() + + + +This action inserts a newline into the text and adds spaces to +that line to indent it to match the previous line. + + + + + + newline-and-backup() + + + +This action inserts a newline into the text after the insert point. + + + + + + newline() + + + +This action inserts a newline into the text before the insert point. + + + + + + + +Kill and Actions + + + + + + + kill-word() + + + + + + + + + + + backward-kill-word() + + + +These actions act exactly like the delete-next-word and +delete-previous-word actions, but they stuff the word that was +killed into the kill buffer (CUT_BUFFER_1). + + + + + + kill-selection() + + + +This action deletes the current selection and stuffs the deleted text into +the kill buffer (CUT_BUFFER_1). + + + + + + kill-to-end-of-line() + + + +This action deletes the entire line to the right of the insert point position, +and stuffs the deleted text into the kill buffer (CUT_BUFFER_1). + + + + + + kill-paragraph() + + + +This action deletes the current paragraph, if between paragraphs it deletes +the paragraph above the insert point, and stuffs the deleted text into +the kill buffer (CUT_BUFFER_1). + + + + + + kill-to-end-of-paragraph() + + + +This action deletes everything between the current insert point location and +the next paragraph boundary, and stuffs the deleted text into the kill +buffer (CUT_BUFFER_1). + + + + + + + +Miscellaneous Actions + + + + + + + redraw-display() + + + +This action recomputes the location of all the text lines on the +display, scrolls the text to vertically center the line containing the insert point +on the screen, clears the entire screen, and redisplays it. + + + + + + insert-file([filename]) + + + +This action activates the insert file popup. The filename +option specifies the default filename to put in the filename buffer of +the popup. If no filename is specified the buffer is empty +at startup. + + + + + + insert-char() + + + +This action may only be attached to a key event. When the +international resource is false, this action +calls XLookupString to translate the event into a (rebindable) Latin-1 +character (sequence) and inserts it into the text at the +insert point. When the international resource is true, +characters are passed to the input method via XwcLookupString, and any +committed string returned is inserted into the text at the insert point. + + + + + + insert-string(string[,string,...]) + + + +This action inserts each string into the text +at the insert point location. Any string +beginning with the characters "0x" followed by an even +number of hexadecimal digits is +interpreted as a hexadecimal constant and the +corresponding string is inserted instead. This +hexadecimal string may represent up to 50 8-bit characters. + When theinternational resource is +true, a hexadecimal string is intrepeted as +being in a multi-byte encoding, and a hexadecimal +or regular string will result in an error message +if it is not legal in the current locale. + + + + + + display-caret(state,when) + + + +This action allows the insert point to be turned on and off. +The state argument specifies the desired state of the insert point. +This value may be any of the string +values accepted for Boolean resources (e.g. on, True, +off, False, etc.). If no arguments are specified, the +default value is True. +The when argument specifies, for EnterNotify or LeaveNotify +events whether or not the focus field in the event is to be examined. +If the second argument is not specified, or specified as something other +than always then if the action is bound to an EnterNotify +or LeaveNotify event, the action will be taken only if the focus +field is True. An augmented binding that might be useful is: + + + + + + + + + + + *Text.Translations: #override \\ + <FocusIn>: display-caret(on) \\n\\ + <FocusOut>: display-caret(off) + + + + + focus-in() + + + + + + + + + + + focus-out() + + + +These actions do not currently do anything. + + + + + + search(direction,[string]) + + + +This action activates the search popup. The direction must be +specified as either forward or backward. The string is +optional and is used as an initial value for the Search for: string. +For further explanation of the search widget see the section on +Text Searches. + + + + + + multiply(value) + + + +The multiply action allows the user to multiply the effects of many of +the text actions. Thus the following action sequence +multiply(10) delete-next-word() will delete 10 words. It does not +matter whether these actions take place in one event or many events. +Using the default translations the key sequence \fIControl-u, +Control-d\fP will delete 4 characters. +Multiply actions can be chained, thus \fImultiply(5) +multiply(5)\fP is the same as multiply(25). If the string +reset is passed to the multiply action the effects of all previous +multiplies are removed and a beep is sent to the display. + + + + + + form-paragraph() + + + +This action removes all the Carriage Returns from the current +paragraph and reinserts them so that each line is as long as possible, while +still fitting on the current screen. Lines are broken at word boundaries if +at all possible. This action currently works only on Text widgets +that use ASCII text. + + + + + + transpose-characters() + + + +This action will swap the position of the character to the left of the +insert point with the character to the right of the insert point. The insert point will then +be advanced one character. + + + + + + no-op([action]) + + + +The no-op action makes no change to the text widget, and is mainly used +to override translations. This action takes one optional argument. If +this argument is RingBell then a beep is sent to the display. + + + + + + XawWMProtocols([wm_protocol_name]) + + + + + +This action is written specifically for the file insertion and the search +and replace +dialog boxes. This action is attached to those shells by the Text widget, +in order to handle ClientMessage events with the WM_PROTOCOLS atom in the +detail field. This action supports WM_DELETE_WINDOW on the Text widget +popups, and may support other window manager protocols if necessary in +the future. The popup will be dismissed if the window manager sends +a WM_DELETE_WINDOW request and there are no parameters in the action +call, which is the default. The popup will also be dismissed if the +parameters include the string ``wm_delete_window,'' and the event is a +ClientMessage event requesting dismissal or is not a ClientMessage event. +This action is not sensitive to the case of the strings passed as parameters. + + + + + + reconnect-im() + + + + +When the international resource is true, +input is usually passed to an input method, a separate +process, for composing. Sometimes the connection to +this process gets severed; this action will attempt to +reconnect it. Causes for severage include network +trouble, and the user explicitly killing one input +method and starting a new one. This action may also +establish first connection when the application is +started before the input method. + + + + + + + +Text Selections for Application Programmers + + + +The default behavior of the text selection array is described in the +section called Text Selections for Users. To modify the selections +a programmer must construct a XawTextSelectType array (called the +selection array), containing the selections desired, and pass this as +the new value for the selectionTypes resource. The selection +array may also be modified using the + +function. All selection arrays must end with the value +XawselectNull. The selectionTypes resource has no converter +registered and cannot be modified through the resource manager. + + + +The array contains a list of entries that will be called when the user +attempts to select text in rapid succession with the select-start +action (usually by clicking a pointer button). The first entry in the +selection array will be used when the select-start action is +initially called. The next entry will be used when select-start +is called again, and so on. If a timeout value (1/10 of a second) is +exceeded, the the next select-start action will begin at the top +of the selection array. When XawselectNull is reached the array +is recycled beginning with the first element. + + + + + + + + XawselectAll + Selects the contents of the entire buffer. + + + XawselectChar + Selects text characters as the pointer moves over them. + + + XawselectLine + Selects the entire line. + + + XawselectNull + Indicates the end of the selection array. + + + XawselectParagraph + Selects the entire paragraph. + + + XawselectPosition + Selects the current pointer position. + + + XawselectWord + Selects whole words as the pointer moves onto them. + + + + + + + +The default selectType array is: + + + + + +{XawselectPosition, XawselectWord, XawselectLine, XawselectParagraph, XawselectAll, XawselectNull} + + + + + +The selection array is not copied by the text widgets. The +application must allocate space for the array and cannot deallocate or +change it until the text widget is destroyed or until a new selection +array is set. + + + diff --git a/specs/TextCustom.xml b/specs/TextCustom.xml new file mode 100644 index 0000000..7ca2d5f --- /dev/null +++ b/specs/TextCustom.xml @@ -0,0 +1,123 @@ + +Customizing the Text Widget + + + + + + + + + +The remainder of this chapter will describe customizing the Text +widget. The Text widget may be customized by subclassing, or by +creating new sources and sinks. Subclassing is described in +detail in Chapter 7; this section will describe only those things that +are specific to the Text widget. Attributes of the Text widget base +class and creating new sources and sinks will be discussed. + + + +The Text widget is made up of a number of different pieces, with the +Text widget as the base widget class. It and the AsciiText widget are +the only true "widgets" in the Text widget family. The other pieces +(sources and sinks) are X Toolkit objects and have no window +associated with them. No source or sink is useful unless assigned to +a Text widget. + + + +Each of the following pieces of the Text widget has a specific purpose, +and will be, or has been, discussed in detail in this chapter: + + + + + + Text + + +This is the glue that binds everything else together. This widget reads +the text data from the source, and displays the information in the sink. +All translations and actions are handled in the Text widget itself. + + + + + + TextSink + + +This object is responsible for displaying and clearing the drawing area. +It also reports the configuration of the window that contains the +drawing area. The TextSink does not have its own window; instead it does +its drawing on the Text widget's window. + + + + + + TextSrc + + +This object is responsible for reading, editing and searching through the +text buffer. + + + + + + AsciiSink + + +This object is a subclass of the TextSink and knows how to display +ASCII text. Support has been added to display any 8-bit character set, given +the font. + + + + + + MultiSink + + +This object is a subclass of the TextSink and knows how to display +font sets. + + + + + + AsciiSrc + + +This object is a subclass of the TextSrc and knows how to read strings +and files. + + + + + + MultiSrc + + +This object is a subclass of the TextSrc and knows how to read strings +and multibyte files, converting them to wide characters based on locale. + + + + + + AsciiText + + +This widget is a subclass of the Text widget. When created, the AsciiText +automatically creates and attaches either an AsciiSrc and AsciiSink, or a +MultiSrc and MultiSink, to itself. The AsciiText provides the simplest +interface to the Athena Text widgets. + + + + + + diff --git a/specs/TextFuncs.xml b/specs/TextFuncs.xml new file mode 100644 index 0000000..d7d3580 --- /dev/null +++ b/specs/TextFuncs.xml @@ -0,0 +1,856 @@ + +Text Functions + + + + + +The following functions are provided as convenience routines for use with +the Text widget. Although many of these actions can be performed by +modifying resources, these interfaces are frequently more efficient. + + + +These data structures are defined in the Text widget's public header file, +<X11/Xaw/Text.h>. + + + + +typedef long XawTextPosition; + + + + +Character positions in the Text widget begin at 0 and end at n, where +n is the number of characters in the Text source widget. + + + + + + + +typedef struct { + int firstPos; + int length; + char *ptr; + unsigned long format; +} XawTextBlock, *XawTextBlockPtr; + + + + + + + + + firstPos + + + +The first position, or index, to use within the ptr field. +The value is commonly zero. + + + + + + length + + + +The number of characters to be used from the ptr field. +The number of characters used is commonly the number of characters +in ptr, and must not be greater than the length of the string +in ptr. + + + + + + ptr + + + +Contains the string to be referenced by the Text widget. + + + + + + format + + + +This flag indicates whether the data pointed to by ptr is char +or wchar_t. When the associated widget has international set +to false this field must be XawFmt8Bit. When the associated +widget has international set to true this field must be +either XawFmt8Bit or XawFmtWide. + + + + + + + + +Note: Previous versions of Xaw used +FMT8BIT , +which has been retained for backwards compatibility. FMT8BIT is +deprecated and will eventually be removed from the implementation. + + + +Selecting Text + + +To select a piece of text, use +XawTextSetSelection : + + + + void XawTextSetSelection + Widget w + XawTextPositionleft, right + + + + + + + w + + + +Specifies the Text widget. + + + + + + left + + + +Specifies the character position at which the selection begins. + + + + + + right + + + +Specifies the character position at which the selection ends. + + + + + + + +See section 5.4 for a description of XawTextPosition. +If redisplay is enabled, this function highlights the text and +makes it the PRIMARY selection. This function does not have any +effect on CUT_BUFFER0. + + + + + + +Unhighlighting Text + + +To unhighlight previously highlighted text in a widget, use +: + + + + void XawTextUnsetSelection + Widget w + + + + + + + w + + + +Specifies the Text widget. + + + + + + + +Getting Current Text Selection + + +To retrieve the text that has been selected by this +text widget use : + + + + void XawTextGetSelectionPos + Widget w + XawTextPosition*begin_return, *end_return + + + + + + + w + + + +Specifies the Text widget. + + + + + + begin_return + + + +Returns the beginning of the text selection. + + + + + + end_return + + + +Returns the end of the text selection. + + + + + + + +See section 5.4 for a description of XawTextPosition. +If the returned values are equal, no text is currently selected. + + + +Replacing Text + + +To modify the text in an editable Text widget use : + + + + int XawTextReplace + Widget w + XawTextPositionstart, end + XawTextBlock *text + + + + + + + w + + + +Specifies the Text widget. + + + + + + start + + + +Specifies the starting character position of the text replacement. + + + + + + end + + + +Specifies the ending character position of the text replacement. + + + + + + text + + + +Specifies the text to be inserted into the file. + + + + + + + +This function will not +be able to replace text in read-only text widgets. It will also only +be able to append text to an append-only text widget. + + + +See section 5.4 for a description of XawTextPosition and +XawTextBlock. + + + +This function may return the following values: + + + + XawEditDone + + + + +The text replacement was successful. + + + + + + XawPositionError + + + + +The edit mode is XawtextAppend and start is not the position of +the last character of the source. + + + + + + XawEditError + + + + +Either the Source was read-only or the range to be deleted is larger +than the length of the Source. + + + + + + + + +The arguments start and +end represent the text source character positions for the +existing text that is to be replaced by the text in the text block. +The characters from start up to +but not including end are deleted, and the characters +specified on the text block are inserted in their place. If +start and end are equal, no text is deleted and the new +text is inserted after start. + + + +Searching for Text + + +To search for a string in the Text widget, use +: + + + + XawTextPosition XawTextSearch + Widget w + XawTextScanDirection dir + XawTextBlock* text + + + + + + + w + + + +Specifies the Text widget. + + + + + + dir + + + +Specifies the direction to search in. Legal values are +XawsdLeft and XawsdRight. + + + + + + text + + + +Specifies a text block structure that contains the text to search for. + + + + + + + +See section 5.4 for a description of XawTextPosition and XawTextBlock. +The function will begin at the insertion point +and search in the +direction specified for a string that matches the one passed in +text. If the string is found the location of the first +character in the string is returned. If the string could not be +found then the value XawTextSearchError is returned. + + + +Redisplaying Text + + +To redisplay a range of characters, use : + + + + void XawTextInvalidate + Widget w + XawTextPositionfrom, to + + + + + + + w + + + +Specifies the Text widget. + + + + + + from + + + +Specifies the start of the text to redisplay. + + + + + + to + + + +Specifies the end of the text to redisplay. + + + + + + + +See section 5.4 for a description of XawTextPosition. +The +function causes the specified range of characters to be redisplayed +immediately if redisplay is enabled or the next time that redisplay is +enabled. + + + + +To enable redisplay, use : + + + + void XawTextEnableRedisplay + Widget w + + + + + + + w + + + +Specifies the Text widget. + + + + + + + +The function flushes any changes due to +batched updates when +was called and allows future changes to be reflected immediately. + + + + +To disable redisplay while making several changes, use +. + + + + void XawTextDisableRedisplay + Widget w + + + + + + + w + + + +Specifies the Text widget. + + + + + + + +The function causes all changes to be +batched until either or +is called. + + + + +To display batched updates, use : + + + + void XawTextDisplay + Widget w + + + + + + + w + + + +Specifies the Text widget. + + + + + + + +The function forces any accumulated updates to be +displayed. + + + +Resources Convenience Routines + + +To obtain the character position of the left-most character on the +first line displayed in the widget (the value of the +displayPosition resource), use . + + + + XawTextPosition XawTextTopPosition + Widget w + + + + + + + w + + + +Specifies the Text widget. + + + + + + + + +To assign a new selection array to a text widget use +: + + + + void XawTextSetSelectionArray + Widget w + XawTextSelectType* sarray + + + + + + + w + + + +Specifies the Text widget. + + + + + + sarray + + + +Specifies a selection array as defined in the section called \fBText +Selections for Application Programmers\fP. + + + + + + + +Calling this function is equivalent to setting the value of the +selectionTypes resource. + + + + +To move the insertion point to the specified source position, use +: + + + + void XawTextSetInsertionPoint + Widget w + XawTextPosition position + + + + + + + w + + + +Specifies the Text widget. + + + + + + position + + + +Specifies the new position for the insertion point. + + + + + + + +See section 5.4 for a description of XawTextPosition. +The text will be scrolled vertically if necessary to make the line +containing the insertion point visible. Calling this function is +equivalent to setting the insertPosition resource. + + + + +To obtain the current position of the insertion point, use +: + + + + XawTextPosition XawTextGetInsertionPoint + Widget w + + + + + + + w + + + +Specifies the Text widget. + + + + + + + +See section 5.4 for a description of XawTextPosition. +The result is equivalent to retrieving the value of the +insertPosition resource. + + + + +To replace the text source in the specified widget, use +: + + + + void XawTextSetSource + Widget w + Widget source + XawTextPosition position + + + + + + + w + + + +Specifies the Text widget. + + + + + + source + + + +Specifies the text source object. + + + + + + position + + + +Specifies character position that will become the upper left hand corner +of the displayed text. This is usually set to zero. + + + + + + + +See section 5.4 for a description of XawTextPosition. +A display update will be performed if redisplay is enabled. + + + + +To obtain the current text source for the specified widget, use +: + + + + Widget XawTextGetSource + Widget w + + + + + + + w + + + +Specifies the Text widget. + + + + + + + +This function returns the text source that this Text widget is currently +using. + + + + +To enable and disable the insertion point, use +: + + + + void XawTextDisplayCaret + Widget w + Boolean visible + + + + + + + w + + + +Specifies the Text widget. + + + + + + visible + + + +Specifies whether or not the caret should be displayed. + + + + + + + +If visible is False the insertion point will be disabled. +The marker is re-enabled either by setting visible to True, by +calling , or by executing the display-caret +action routine. + + + diff --git a/specs/TextSink.xml b/specs/TextSink.xml new file mode 100644 index 0000000..93a2e0e --- /dev/null +++ b/specs/TextSink.xml @@ -0,0 +1,917 @@ + +TextSink Object + + + + + + + + + + + + +Application Header file <X11/Xaw/TextSink.h> + +Class Header file <X11/Xaw/TextSinkP.h> + +Class textSinkObjectClass + +Class Name TextSink + +Superclass Object + + + + +The TextSink object is the root object for all text sinks. Any new text +sink objects should be subclasses of the TextSink Object. The TextSink +Class contains all methods that the Text widget expects a text sink to +export. + + + +Since all text sinks will have some resources in common, the TextSink +defines a few new resources. + + +Resources + + +When creating an TextSink object instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + background + Background + Pixel + + XtDefaultBackground + + + destroyCallback + Callback + XtCallbackList + + NULL + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + _ + + + + + + + + + + +Subclassing the TextSink + + + +The only purpose of the TextSink Object is to be subclassed. It +contains the minimum set of class methods that all text sinks must have. +While all may be inherited, the direct descendant of TextSink must +specify some of them as TextSink does contain enough information to +be a valid text sink by itself. Do not try to use +the TextSink as a valid sink for the Text widget; it is not intended +to be used as a sink by itself. + + + + + + + + + Function + Inherit with + Public Interface + must specify + + + + + DisplayText + XtInheritDisplayText + XawTextSinkDisplayText + yes + + + InsertCursor + XtInheritInsertCursor + XawTextSinkInsertCursor + yes + + + ClearToBackground + XtInheritClearToBackground + XawTextSinkClearToBackground + no + + + FindPosition + XtInheritFindPosition + XawTextSinkFindPosition + yes + + + FindDistance + XtInheritFindDistance + XawTextSinkFindDistance + yes + + + Resolve + XtInheritResolve + XawTextSinkResolve + yes + + + MaxLines + XtInheritMaxLines + XawTextSinkMaxLines + no + + + MaxHeight + XtInheritMaxHeight + XawTextSinkMaxHeight + no + + + SetTabs + XtInheritSetTabs + XawTextSinkSetTabs + no + + + GetCursorBounds + XtInheritGetCursorBounds + XawTextSinkGetCursorBounds + yes + + + + + + +Displaying Text + + +To display a section of the text buffer contained in the text source +use the function : + + + + void DisplayText + Widget w + Positionx, y + XawTextPositionpos1, pos2 + Boolean highlight + + + + + + + w + + + +Specifies the TextSink object. + + + + + + x + + + +Specifies the x location to start drawing the text. + + + + + + y + + + +Specifies the y location to start drawing text. + + + + + + pos1 + + + +Specifies the location within the text source of the first character +to be printed. + + + + + + pos2 + + + +Specifies the location within the text source of the last character +to be printed. + + + + + + highlight + + + +Specifies whether or not to paint the text region highlighted. + + + + + + + +The Text widget will only pass one line at a time to the text sink, so +this function does not need to know how to line feed the text. It is +acceptable for this function to just ignore Carriage Returns. x +and y denote the upper left hand corner of the first character to +be displayed. + + + +Displaying the Insert Point + + +The function that controls the display of the text cursor is +. This function will be called whenever the text +widget desires to change the state of, or move the insert point. + + + void InsertCursor + Widget w + Positionx, y + XawTextInsertState state + + + + + + + w + + + +Specifies the TextSink object. + + + + + + x + + + +Specifies the x location of the cursor in Pixels. + + + + + + y + + + +Specifies the y location of the cursor in Pixels. + + + + + + state + + + +Specifies the state of the cursor, may be one of XawisOn or +XawisOff. + + + + + + + +X and y denote the upper left hand corner of the insert point. + + + +Clearing Portions of the Text window + + +To clear a portion of the Text window to its background color, the Text +widget will call . The TextSink object already +defines this function as calling +XClearArea +on the region passed. +This behavior will be used if you specify +XtInheritClearToBackground for this method. + + + + + void ClearToBackground + Widget w + Positionx, y + Dimensionwidth, height + + + + + + + w + + + +Specifies the TextSink object. + + + + + + x + + + +Specifies the x location, in pixels, of the Region to clear. + + + + + + y + + + +Specifies the y location, in pixels, of the Region to clear. + + + + + + width + + + +Specifies the width, in pixels, of the Region to clear. + + + + + + height + + + +Specifies the height, in pixels, of the Region to clear. + + + + + + + +X and y denote the upper left hand corner of region to clear. + + + +Finding a Text Position Given Pixel Values + + +To find the text character position that will be rendered at a given x +location the Text widget uses the function : + + + + void FindPosition + Widget w + XawTextPosition fromPos + intfromX, width + Boolean stopAtWordBreak + XawTextPosition *pos_return + int*width_return, *height_return + + + + + + + w + + + +Specifies the TextSink object. + + + + + + fromPos + + + +Specifies a reference position, usually the first character in this line. +This character is always to the left of the desired character location. + + + + + + fromX + + + +Specifies the distance that the left edge of fromPos is from the +left edge of the window. This is the reference x location for the +reference position. + + + + + + width + + + +Specifies the distance, in pixels, from the reference position to the +desired character position. + + + + + + stopAtWordBreak + + + +Specifies whether or not the position that is returned should be forced +to be on a word boundary. + + + + + + pos_return + + + +Returns the character position that corresponds to the location that has +been specified, or the work break immediately to the left of the +position if stopAtWordBreak is True. + + + + + + width_return + + + +Returns the actual distance between fromPos and pos_return. + + + + + + height_return + + + +Returns the maximum height of the text between fromPos and +pos_return. + + + + + + + +This function need make no attempt to deal with line feeds. The text +widget will only call it one line at a time. + + + + +Another means of finding a text position is provided by the +function: + + + + void Resolve + Widget w + XawTextPosition fromPos + intfromX, width + XawTextPosition *pos_return + + + + + + + w + + + +Specifies the TextSink object. + + + + + + fromPos + + + +Specifies a reference position, usually the first character in this line. +This character is always to the left of the desired character location. + + + + + + fromX + + + +Specifies the distance that the left edge of fromPos is from the +left edge of the window. This is the reference x location for the +reference position. + + + + + + width + + + +Specifies the distance, in pixels, from the reference position to the +desired character position. + + + + + + pos_return + + + +Returns the character position that corresponds to the +location that has been specified, or the word break immediately to the left +if stopAtWordBreak is True. + + + + + + + +This function need make no attempt to deal with line feeds. The text +widget will only call it one line at a time. This is a more convenient +interface to the function, and provides a subset of its +functionality. + + + + +Finding the Distance Between two Text Positions + + +To find the distance in pixels between two text positions on the same +line use the function . + + + + void FindDistance + Widget w + XawTextPositionfromPos, toPos + int fromX + XawTextPosition *pos_return + int*width_return, *height_return + + + + + + + w + + + +Specifies the TextSink object. + + + + + + fromPos + + + +Specifies the text buffer position, in characters, of the first position. + + + + + + fromX + + + +Specifies the distance that the left edge of fromPos is from the +left edge of the window. This is the reference x location for the +reference position. + + + + + + toPos + + + +Specifies the text buffer position, in characters, of the second position. + + + + + + resWidth + + + +Return the actual distance between fromPos +and pos_return. + + + + + + resPos + + + +Returns the character position that corresponds to the actual character +position used for toPos in the calculations. This may be +different than toPos, for example if fromPos and toPos +are on different lines in the file. + + + + + + height_return + + + +Returns the maximum height of the text between fromPos and +pos_return. + + + + + + + +This function need make no attempt to deal with line feeds. The Text +widget will only call it one line at a time. + + + +Finding the Size of the Drawing area + + +To find the maximum number of lines that will fit into the current Text +widget, use the function . The TextSink already defines +this function to compute the maximum number of lines by using the height +of font. + + + + int MaxLines + Widget w + Dimension height + + + + + + + w + + + +Specifies the TextSink object. + + + + + + height + + + +Specifies the height of the current drawing area. + + + + + + + +Returns the maximum number of lines that will fit in height. + + + + +To find the height required for a given number of text lines, use +the function . The TextSink already defines this +function to compute the maximum height of the window by using the +height of font. + + + + int MaxHeight + Widget w + int lines + + + + + + + w + + + +Specifies the TextSink object. + + + + + + height + + + +Specifies the height of the current drawing area. + + + + + + + +Returns the height that will be taken up by the number of lines passed. + + + +Setting the Tab Stops + + +To set the tab stops for a text sink use the function. +The TextSink already defines this function to set the tab x location in +pixels to be the number of characters times the figure width of +font. + + + + void SetTabs + Widget w + inttab_count, *tabs + + + + + + + w + + + +Specifies the TextSink object. + + + + + + tab_count + + + +Specifies the number of tabs passed in tabs. + + + + + + tabs + + + +Specifies the position, in characters, of the tab stops. + + + + + + + +This function is responsible for the converting character positions passed +to it into whatever internal positions the TextSink uses for tab placement. + + + +Getting the Insert Point's Size and Location + + +To get the size and location of the insert point use the + function. + + + + void GetCursorBounds + Widget w + XRectangle *rect_return + + + + + + + w + + + +Specifies the TextSinkObject. + + + + + + rect_return + + + +Returns the location and size of the insert point. + + + + + + + +Rect will be filled with the current size and location of the +insert point. + + + + + diff --git a/specs/TextSource.xml b/specs/TextSource.xml new file mode 100644 index 0000000..c90ae29 --- /dev/null +++ b/specs/TextSource.xml @@ -0,0 +1,620 @@ + +TextSrc Object + +Application Header file <X11/Xaw/TextSrc.h> +Class Header file <X11/Xaw/TextSrcP.h> +Class textSrcObjectClass +Class Name TextSrc +Superclass Object + + + + +The TextSrc object is the root object for all text sources. Any new text +source objects should be subclasses of the TextSrc Object. The +TextSrc Class contains all methods the Text widget expects a text +source to export. + + + + +Since all text sources will have some resources in common the +TextSrc defines a few new resources. + + + +Resources + +When creating an TextSrc object instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + destroyCallback + Callback + XtCallbackList + + NULL + + + editType + EditType + EditMode + + NULL + + + + + + + +Subclassing the TextSrc + +The only purpose of the TextSrc Object is to be subclassed. It contains +the minimum set of class methods that all text sources must have. All +class methods of the TextSrc must be defined, as the Text widget uses +them all. While all may be inherited, the direct descendant of TextSrc +must specify some of them as TextSrc does not contain enough +information to be a valid text source by itself. Do not try to use the +TextSrc as a valid source for the Text widget; it is not intended to be +used as a source by itself and bad things will probably happen. + + + + + + + + + + + Function + Inherit with + Public Interface + must specify + + + + + Read + XtInheritRead + XawTextSourceRead + yes + + + Replace + XtInheritReplace + XawTextSourceReplace + no + + + Scan + XtInheritScan + XawTextSourceScan + yes + + + Search + XtInheritSearch + XawTextSourceSearch + no + + + SetSelection + XtInheritSetSelection + XawTextSourceSetSelection + no + + + ConvertSelection + XtInheritConvertSelection + XawTextSourceConvertSelection + no + + + + + + +Reading Text. + + +To read the text in a text source use the function: + + + + + XawTextPosition Read + Widget w + XawTextPosition pos + XawTextBlock *text_return + int length + + + + + + + + w + + + +Specifies the TextSrc object. + + + + + + pos + + + +Specifies the position of the first character to be read from the text buffer. + + + + + text + + +Returns the text read from the source. + + + + + + length + + + +Specifies the maximum number of characters the TextSrc should +return to the application in text_return. + + + + + + +This function returns the text position immediately after the +characters read from the +text buffer. The function is not required to read length +characters if that many characters are in the file, it may break at +any point that is convenient to the internal structure of the +source. It may take several calls to before the desired +portion of the text buffer is fully retrieved. + + + + +Replacing Text. + +To replace or edit the text in a text buffer use the function: + + + + + XawTextPosition Replace + Widget w + XawTextPositionstart, end + XawTextBlock *text + + + + + + w + + +Specifies the TextSrc object. + + + + + start + + +Specifies the position of the first character to be removed from the text +buffer. This is also the location to begin inserting the new text. + + + + + end + + +Specifies the position immediately after the last character to be +removed from the text buffer. + + + + + text + + +Specifies the text to be added to the text source. + + + + + + +This function can return any of the following values: + + + + + XawEditDone + + +The text replacement was successful. + + + + + XawPositionError + + + +The edit mode is XawtextAppend and start is not the last +character of the source. + + + + + XawEditError + + + +Either the Source was read-only or the range to be deleted is larger +than the length of the Source. + + + + + + + +The arguments start and end represent the +text source character positions for the existing text that is to be +replaced by the text in the text block. The characters from +start up to but not including end are deleted, and the +buffer specified by the text block is inserted in their +place. If start and end are equal, no text is deleted and +the new text is inserted after start. + + + + +Scanning the TextSrc + +To search the text source for one of the predefined boundary types use +the function: + + + + + XawTextPosition Scan + Widget w + XawTextPosition position + XawTextScanType type + XawTextScanDirection dir + int count + Boolean include + + + + + + + w + + +Specifies the TextSrc object. + + + + + position + + +Specifies the position to begin scanning the source. + + + + + type + + +Specifies the type of boundary to scan for, may be one of: +XawstPosition, XawstWhiteSpace, XawstEOL, +XawstParagraph, XawstAll. The exact meaning of these +boundaries is left up to the individual text source. + + + + + dir + + +Specifies the direction to scan, may be either XawsdLeft to search + +backward, or XawsdRight to search forward. + + + + + + count + + +Specifies the number of boundaries to scan for. + + + + + include + + +Specifies whether the boundary itself should be included in the scan. + + + + + + + +The function returns the position in the text source of the desired +boundary. It is expected to return a valid address for +all calls made to it, thus if a particular request is made that would take +the text widget beyond the end of the source it must return the +position of that end. + + + + +Searching through a TextSrc + +To search for a particular string use the function. + + + + + XawTextPosition Search + Widget w + XawTextPosition position + XawTextScanDirection dir + XawTextBlock *text + + + + + + w + + +Specifies the TextSrc object. + + + + + position + + +Specifies the position to begin the search. + + + + + dir + + +Specifies the direction to search, may be either XawsdLeft to search + +backward, or XawsdRight to search forward. + + + + + + text + + +Specifies a text block containing the text to search for. + + + + + + +This function will search through the text buffer attempting to find a +match for the string in the text block. If a match is found in the +direction specified, then the character location of the first character +in the string is returned. If no text was found then +XawTextSearchError is returned. + + + + + +Text Selections + + + +While many selection types are handled by the Text widget, text sources +may have selection types unknown to the Text widget. When a selection +conversion is requested by the X server the Text widget will first call +the ConvertSelection function, to attempt the selection +conversion. + + + + + Boolean ConvertSelections + Widget w + Atom*selection,*target, *type + caddr_t *value_return + unsignedlong *length_return + int *format_return + + + + + + + w + + + +Specifies the TextSrc object. + + + + + + selection + + + +Specifies the type of selection that was requested (e.g. PRIMARY). + + + + + + target + + + +Specifies the type of the selection that has been requested, which +indicates the desired information about the selection (e.g. Filename, +Text, Window). + + + + + + type + + + +Specifies a pointer to the atom into which the property type of the converted +value of the selection is to be stored. For instance, either file +name or text might have property type XA_STRING. + + + + + + value_return + + + +Returns a pointer into which a pointer to the converted value of the +selection +is to be stored. The selection owner is responsible for allocating +this storage. The memory is considered owned by the toolkit, and is +freed by XtFree when the Intrinsics selection mechanism is done with it. + + + + + + length_return + + + +Returns a pointer into which the number of elements in value is to be stored. +The size of each element is determined by format. + + + + + + format_return + + + +Returns a pointer into which the size in bits of the data elements of the +selection value is to be stored. + + + + + + +If this function returns True then the Text widget will assume +that the source has taken care of converting the selection, Otherwise the +Text widget will attempt to convert the selection itself. + + + +If the source needs to know when the text selection is modified it +should define a procedure: + + + + + void SetSelection + Widget w + XawTextPositionstart, end + Atom selection + + + + + + w + + +Specifies the TextSrc object. + + + + + start + + +Specifies the character position of the beginning of the new text selection. + + + + + end + + +Specifies the character position of the end of the new text selection. + + + + + selection + + +Specifies the type of selection that was requested (e.g. PRIMARY). + + + + + + + + diff --git a/specs/Toggle.xml b/specs/Toggle.xml new file mode 100644 index 0000000..227aba2 --- /dev/null +++ b/specs/Toggle.xml @@ -0,0 +1,773 @@ + +Toggle Widget + +Application Header file <Xaw/Toggle.h> +Class Header file <Xaw/ToggleP.h> +Class toggleWidgetClass +Class Name Toggle +Superclass Command + + + +The Toggle widget is an area, often rectangular, +that displays a graphic. The graphic may be a text +string containing multiple lines of characters in an 8 +bit or 16 bit character set (to be displayed with a +font), or in a multi-byte encoding (for use with +a fontset). The graphic may also be a bitmap or +pixmap. + + + +This widget maintains a Boolean state (e.g. +True/False or On/Off) and changes state whenever it is selected. When +the pointer is on the Toggle widget, the Toggle widget may become highlighted by +drawing a rectangle around its perimeter. This highlighting indicates +that the Toggle widget is ready for selection. When pointer button 1 is +pressed and released, the Toggle widget indicates that it has changed +state by reversing its foreground and background colors, and its +notify action is invoked, calling all functions on its callback +list. If the pointer is moved off of the widget before the pointer button is +released, the Toggle widget reverts to its previous foreground and background +colors, and releasing the pointer button has no effect. This behavior allows +the user to cancel the operation. + + + +Toggle widgets may also be part of a ``radio group.'' A radio group is a +list of at least two Toggle widgets in which no more than one Toggle may +be set at +any time. A radio group is identified by the widget ID of any one of +its members. The convenience routine will +return information about the Toggle widget in the radio group. + + + +Toggle widget state is preserved across changes in sensitivity. + + + +Resources + +When creating a Toggle widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + bitmap + Bitmap + Pixmap + + None + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + callback + Callback + XtCallbackList + + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + cornerRoundPercent + CornerRoundPercent + Dimension + + 25 + + + cursor + Cursor + Cursor + + None + + + cursorName + Cursor + String + + NULL + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + encoding + Encoding + UnsignedChar + + XawTextEncoding8bit + + + font + Font + XFontStruct + + XtDefaultFont + + + fontSet + FontSet + XFontSet + + XtDefaultFontSet + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + height + Height + Dimension + A + graphic height + 2 * internalHeight + + + highlightThickness + Thickness + Dimension + A + 2 (0 if Shaped) + + + insensitiveBorder + Insensitive + Pixmap + + GreyPixmap + + + internalHeight + Height + Dimension + + 2 + + + internalWidth + Width + Dimension + + 4 + + + international + International + Boolean + C + False + + + justify + Justify + Justify + + XtJustifyCenter (center) + + + label + Label + String + + name of widget + + + leftBitmap + LeftBitmap + Bitmap + + None + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + pointerColor + Foreground + Pixel + + XtDefaultForeground + + + pointerColorBackground + Background + Pixel + + XtDefaultBackground + + + radioData + RadioData + Pointer + + Name of widget + + + radioGroup + Widget + Widget + + No radio group + + + resize + Resize + Boolean + + True + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + shapeStype + ShapeStyle + ShapeStyle + + Rectangle + + + state + State + Boolean + + Off + + + translations + Translations + TranslationTable + + See below + + + width + Width + Dimension + A + graphic width + 2 * internalWidth + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + + radioData + + + +Specifies the data that will be returned by +when this is the currently set widget in the radio group. This +value is also used to identify the Toggle that will be set by a call to +. The value NULL will be returned by + if no widget in a radio group is currently +set. Programmers must not specify NULL (or Zero) as radioData. + + + + + + radioGroup + + + +Specifies another Toggle widget that is in the radio group to which this +Toggle widget should be added. A radio group is a group of at least two Toggle +widgets, only one of which may be set at a time. If this value is +NULL (the default) then the Toggle will not be part of any radio group +and can change state without affecting any other Toggle widgets. If the +widget specified in this resource is not already in a radio group then a +new radio group will be created containing these two Toggle widgets. No +Toggle widget can be in multiple radio groups. The behavior of a radio +group of one toggle is undefined. A converter is registered which will +convert widget names to widgets without caching. + + + + + + state + + + +Specifies whether the Toggle widget is set (True) or unset +(False). + + + + + + + +Toggle Actions + +The Toggle widget supports the following actions: + + + + + +Switching the Toggle widget between the foreground and background +colors with set and unset and toggle + + + + +Processing application callbacks with notify + + + + +Switching the internal border between highlighted +and unhighlighted states with highlight and unhighlight + + + + + +The following are the default translation bindings used by the +Toggle widget: + + + + <EnterWindow>: highlight(Always) + <LeaveWindow>: unhighlight() + <Btn1Down>,<Btn1Up>: toggle() notify() + + + + +Toggle Actions + +The full list of actions supported by Toggle is: + + + + + highlight(condition) + + + +Displays the internal highlight border in the color (foreground +or background ) that contrasts with the interior color of the +Toggle widget. The conditions WhenUnset and Always are +understood by this action procedure. If no argument is passed then +WhenUnset is assumed. + + + + + + unhighlight() + + + +Displays the internal highlight border in the color (foreground +or background ) that matches the interior color of the +Toggle widget. + + + + + + set() + + + +Enters the set state, in which notify is possible. This +action causes the Toggle widget to display its interior in the +foreground color. The label or bitmap is displayed in the +background color. + + + + + + unset() + + + +Cancels the set state and displays the interior of the Toggle widget in the +background color. The label or bitmap is displayed in the +foreground color. + + + + + + toggle() + + + +Changes the current state of the Toggle widget, causing to be set +if it was previously unset, and unset if it was previously set. +If the widget is to be set, and is in a radio group then this procedure may +unset another Toggle widget causing all routines on its callback list +to be invoked. The callback routines for the Toggle that +is to be unset will be called before the one that is to be set. + + + + + + reset() + + + +Cancels any set or highlight and displays the interior of the +Toggle widget in the background color, with the label displayed in the +foreground color. + + + + + + notify() + + + +When the Toggle widget is in the set state this action calls all functions in +the callback list named by the callback resource. The value of +the call_data argument in these callback functions is undefined. + + + + + + +When a bitmap of depth greater that one (1) is specified the +set(), unset(), and reset() actions have no effect, +since there are no foreground and background colors used in a +multi-plane pixmap. + + + + +Radio Groups + +There are typically two types of radio groups desired by applications. +The default translations for the Toggle widget implement a "zero or one + +of many" radio group. This means that there may be no more than one +Toggle widget active, but there need not be any Toggle widgets active. + + + +The other type of radio group is "one of many" and has the more strict +policy that there will always be exactly one radio button active. +Toggle widgets can be used to provide this interface with a slight +modification to the translation table of each Toggle in the group. + + + + <EnterWindow>: highlight(Always) + <LeaveWindow>: unhighlight() + <Btn1Down>,<Btn1Up>: set() notify() + + + +This translation table will not allow any Toggle to be unset +except as a result of another Toggle becoming set. It is +the application programmer's responsibility to choose an initial +state for the radio group by setting the state resource of one of +its member widgets to True. + + + + +Convenience Routines + +The following functions allow easy access to the Toggle widget's radio +group functionality. + + + +Changing the Toggle's Radio Group. + +To enable an application to change the Toggle's radio group, add +the Toggle to a radio group, or remove the Toggle from a radio group, use +. + + + + + void XawToggleChangeRadioGroup + Widgetw, radio_group + + + + + + + + w + + + +Specifies the Toggle widget. + + + + + + radio_group + + + +Specifies any Toggle in the new radio group. If NULL then the Toggle +will be removed from any radio group of which it is a member. + + + + + + + +If a Toggle is already set in the new radio group, +and the Toggle to be added is also set then the previously +set Toggle in the radio group is unset and its callback +procedures are invoked. +Finding the Currently selected Toggle in a radio group of Toggles + + + +To find the currently selected Toggle in a radio group of Toggle widgets +use . + + + + + XtPointer XawToggleGetCurrent + XtPointer XawToggleGetCurrent(radio_group) + Widget radio_group + + + + + + + radio_group + + + +Specifies any Toggle widget in the radio group. + + + + + + +The value returned by this function is the +radioData +of the Toggle in this radio group that is currently set. The default +value for radioData +is the name of that Toggle widget. If no Toggle is set in the radio +group specified then NULL is returned. +Changing the Toggle that is set in a radio group. + + + +To change the Toggle that is currently set in a radio group use +. + + + + + void XawToggleSetCurrent + voidXawToggleSetCurrent(radio_group, radio_data) + Widget radio_group + XtPointer radio_data + + + + + + + radio_group + + + +Specifies any Toggle widget in the radio group. + + + + + + radio_data + + + +Specifies the +radioData +identifying the Toggle that should be set in the radio group specified +by the radio_group argument. + + + + + + + + locates the Toggle widget to be set by +matching radio_data against the radioData for each Toggle in +the radio group. If none match, returns +without making any changes. If more than one Toggle matches, + will choose a Toggle to set arbitrarily. If +this causes any Toggle widgets to change state, all routines in their +callback lists will be invoked. The callback routines for a Toggle that +is to be unset will be called before the one that is to be set. +Unsetting all Toggles in a radio group. + + + +To unset all Toggle widgets in a radio group use +. + + + + + void XawToggleUnsetCurrent + void XawToggleUnsetCurrent(radio_group) + Widget radio_group + + + + + + + radio_group + + + +Specifies any Toggle widget in the radio group. + + + + + + +If this causes a Toggle widget to change state, all routines on its +callback list will be invoked. + + + + diff --git a/specs/Tree.xml b/specs/Tree.xml new file mode 100644 index 0000000..71cadd1 --- /dev/null +++ b/specs/Tree.xml @@ -0,0 +1,404 @@ + +Tree Widget + +Application Header file <X11/Xaw/Tree.h> +Class Header file <X11/Xaw/TreeP.h> +Class treeWidgetClass +Class Name Tree +Superclass Constraint + + + +The Tree widget provides geometry management of arbitrary widgets arranged +in a directed, acyclic graph (i.e., a tree). The hierarchy is constructed +by attaching a constraint resource called treeParent to each widget +indicating which other node in the tree should be treated as the widget's +superior. The structure of the tree is shown by laying out the nodes +in the standard format for tree diagrams with lines drawn connecting each +node with its children. + + + +The Tree sizes itself according to the needs of its children and is not +intended to be resized by its parent. Instead, it should be placed inside +another composite widget (such as the Porthole or Viewport) +that can be used to scroll around in the tree. + + + +Resources + +When creating a Tree widget instance, the following resources are +retrieved from the argument list or from the resource database: + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + autoReconfigure + AutoReconfigure + Boolean + + False + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + children + ReadOnly + WidgetList + R + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + foreground + Foreground + Pixel + + XtDefaultForeground + + + gravity + Gravity + XtGravity + + WestGravity + + + height + Height + Dimension + A + see Layout Semantics + + + hSpace + HSpace + Dimension + + 4 + + + lineWidth + LineWidth + Dimension + + 0 + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + numChildren + ReadOnly + Cardinal + R + 0 + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + vSpace + VSpace + Dimension + + 4 + + + translations + Translations + TranslationTable + + NULL + + + width + Width + Dimension + A + see Layout Semantics + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + + + + + + autoReconfigure + + +Whether or not to layout the tree every time a node is added or removed. + + + + + gravity + + +Specifies the side of the widget from which the tree should grow. Valid +values include WestGravity, NorthGravity, EastGravity, and +SouthGravity. + + + + + hSpace + + + + + + + + + vSpace + + +The amount of space, in pixels, to leave between the children. This +resource specifies the amount of space left between the outermost +children and the edge of the box. + + + + + lineWidth + + +The width of the lines from nodes that do not have a treeGC +constraint resource to their children. + + + + + + + + +Constraint Resources + +Each child of the Tree widget must specify its superior node in the tree. In +addition, it may specify a GC to use when drawing a line between it and its +inferior nodes. + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + treeGC + TreeGC + GC + + NULL + + + treeParent + TreeParent + Widget + + NULL + + + + + + + + + + treeGC + + +This specifies the GC to use when drawing lines between this widget and its +inferiors in the tree. If this resource is not specified, the Tree's +foreground and lineWidth will be used. + + + + + treeParent + + +This specifies the superior node in the tree for this widget. The default is +for the node to have no superior (and to therefore be at the top of the tree). + + + + + + + + + +Layout Semantics + +Each time a child is managed or unmanaged, the Tree widget will attempt +to reposition the remaining children to fix the shape of the tree if the + +resource is set. Children at the top (most superior) of the tree are +drawn at the side specified by the resource. + + + +After positioning all children, the Tree widget attempts to shrink its +own size to the minimum dimensions required for the layout. + + + + + +Convenience Routines + +The most efficient way to layout a tree is to set +autoReconfigure +to False and then use the + +routine to arrange the children. + + + + + void XawTreeForceLayout + Widget w + + + + + + w + + +Specifies the Tree widget. + + + + + + diff --git a/specs/Viewport.xml b/specs/Viewport.xml new file mode 100644 index 0000000..767dc07 --- /dev/null +++ b/specs/Viewport.xml @@ -0,0 +1,391 @@ + +Viewport Widget + + + + + + + + + + +Application Header file <X11/Xaw/Viewport.h> + +Class Header file <X11/Xaw/ViewportP.h> + +Class viewportWidgetClass + +Class Name Viewport + +Superclass Form + + + + + +The Viewport widget consists of a frame window, one or two Scrollbars, +and an inner window. The size of the frame window is determined by the +viewing size of the data that is to be displayed and the dimensions to +which the Viewport is created. The inner window is the full size of the +data that is to be displayed and is clipped by the frame window. The +Viewport widget controls the scrolling of the data directly. No +application callbacks are required for scrolling. + + + +When the geometry of the frame window is equal in size to the inner +window, or when the data does not require scrolling, the Viewport widget +automatically removes any scrollbars. The forceBars option causes +the Viewport widget to display all scrollbars permanently. + + +Resources + + +When creating a Viewport widget instance, the following resources are +retrieved from the argument list or the resource database: + + + + + + + + + + + + + + Name + Class + Type + Notes + Default Value + + + + + accelerators + Accelerators + AcceleratorTable + + NULL + + + allowHoriz + Boolean + Boolean + + False + + + allowVert + Boolean + Boolean + + False + + + ancestorSensitive + AncestorSensitive + Boolean + D + True + + + background + Background + Pixel + + XtDefaultBackground + + + backgroundPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderColor + BorderColor + Pixel + + XtDefaultForeground + + + borderPixmap + Pixmap + Pixmap + + XtUnspecifiedPixmap + + + borderWidth + BorderWidth + Dimension + + 1 + + + children + ReadOnly + WidgetList + R + NULL + + + colormap + Colormap + Colormap + + Parent's Colormap + + + depth + Depth + int + C + Parent's Depth + + + destroyCallback + Callback + XtCallbackList + + NULL + + + forceBars + Boolean + Boolean + + False + + + height + Height + Dimension + + height of the child + + + mappedWhenManaged + MappedWhenManaged + Boolean + + True + + + numChildren + ReadOnly + Cardinal + R + 0 + + + reportCallback + ReportCallback + XtCallbackList + + NULL + + + screen + Screen + Screen + R + Parent's Screen + + + sensitive + Sensitive + Boolean + + True + + + translations + Translations + TranslationTable + + NULL + + + useBottom + Boolean + Boolean + + False + + + useRight + Boolean + Boolean + + False + + + width + Width + Dimension + + width of the child + + + x + Position + Position + + 0 + + + y + Position + Position + + 0 + + + _ + + + + + + + + + allowHoriz + + + + + + + + + + + allowVert + + + +If these resources are False then the Viewport will never create +a scrollbar in this direction. If it is True then the scrollbar will +only appear when it is needed, unless forceBars is True. + + + + + + + + + + + + + + + + forceBars + + + +When True the scrollbars that have been allowed will always be +visible on the screen. If False the scrollbars will be visible only +when the inner window is larger than the frame. + + + + + + + + + reportCallback + + + +These callbacks will be executed whenever the Viewport adjusts the viewed +area of the child. The call_data parameter is a pointer to an XawPannerReport +structure. + + + + + + + + + useBottom + + + + + + + + + + + useRight + + + +By default the scrollbars appear on the left and top of the screen. +These resources allow the vertical scrollbar to be placed on the right +edge of the Viewport, and the horizontal scrollbar on the bottom edge of +the Viewport. + + + + + + + + +Layout Semantics + + + +The Viewport widget manages a single child widget. When the size of the +child is larger than the size of the Viewport, the user can interactively +move the child within the Viewport by repositioning the scrollbars. + + + +The default size of the Viewport before it is realized is the width and/or +height of the child. After it is realized, the Viewport will allow its +child to grow vertically or horizontally if allowVert or +allowHoriz are set, respectively. If the corresponding vertical +or horizontal scrollbar is not enabled, the Viewport will propagate the +geometry request to its own parent and the child will be allowed to change +size only if the Viewport's parent allows it. Regardless of whether or not +scrollbars are enabled in the corresponding direction, if the child requests +a new size smaller than the Viewport size, the change will be allowed only +if the parent of the Viewport allows the Viewport to shrink to the +appropriate dimension. + + + +The scrollbar children of the Viewport are named horizontal and +vertical. By using these names the programmer can specify resources +for the individual scrollbars. can be used to modify +the resources dynamically once the widget ID has been obtained with +XtNameToWidget. + + + + +Although the Viewport is a Subclass of the Form, no resources for the Form +may be supplied for any of the children of the Viewport. These constraints +are managed internally and are not meant for public consumption. + + + + + diff --git a/specs/libXaw.xml b/specs/libXaw.xml new file mode 100644 index 0000000..75880ad --- /dev/null +++ b/specs/libXaw.xml @@ -0,0 +1,89 @@ + + %defs; +]> + + + + + Athena Widget Set - C Language Interface + X Consortium Standard + X Version 11, Release &fullrelvers; + + + ChrisD.Peterson + formerly MIT X Consortium + + + 1985198619871988 + 198919911994 + X Consortium + + + + + +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 X CONSORTIUM 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. + + + +Except as contained in this notice, the name of the X Consortium shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +X Window System is a trademark of The OpenGroup. + + + +Copyright © 1985, 1986, 1987, 1988, 1989, 1991 +Digital Equipment Corporation, Maynard, Massachusetts. + + + +Permission to use, copy, modify and distribute this documentation for any +purpose and without fee is hereby granted, provided that the above copyright +notice appears in all copies and that both that copyright notice and this +permission notice appear in supporting documentation, and that the name of +Digital not be used in in advertising or publicity pertaining +to distribution of the software without specific, written prior permission. +Digital makes no representations about the suitability of the +software described herein for any purpose. +It is provided “as is” without express or implied warranty. + + + + + + + + + + + + + + diff --git a/src/Actions.c b/src/Actions.c new file mode 100644 index 0000000..3a444b8 --- /dev/null +++ b/src/Actions.c @@ -0,0 +1,1136 @@ +/* + * Copyright (c) 1998 by The XFree86 Project, Inc. + * + * 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 XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#ifdef __UNIXOS2__ +static char dummy; +#endif + +#ifndef OLDXAW + +/* + * Definitions + */ +#define ERROR -2 +#define END -1 +#define BOOLEAN 0 +#define AND '&' +#define OR '|' +#define XOR '^' +#define NOT '~' +#define LP '(' +#define RP ')' + +/* + * Types + */ +/* boolean expressions */ +typedef struct _XawEvalInfo { + Widget widget; + XawActionResList *rlist; + XawActionVarList *vlist; + XawParseBooleanProc parse_proc; + XEvent *event; + char *cp, *lp; + int token; + Bool value; +} XawEvalInfo; + +/* resources */ +typedef struct _XawActionRes { + XrmQuark qname; + XrmQuark qtype; + Cardinal size; +} XawActionRes; + +struct _XawActionResList { + WidgetClass widget_class; + XawActionRes **resources; + Cardinal num_common_resources; + Cardinal num_constraint_resources; +}; + +/* variables */ +typedef struct _XawActionVar { + XrmQuark qname; + XrmQuark qvalue; +} XawActionVar; + +struct _XawActionVarList { + Widget widget; + Cardinal num_variables; + XawActionVar **variables; +}; + +/* + * Private methods + */ +/* expressions */ +static int get_token(XawEvalInfo*); +static Bool expr(XawEvalInfo*); +static Bool and(XawEvalInfo*); +static Bool prim(XawEvalInfo*); + +/* resources */ +static String XawConvertActionRes(XawActionResList*, Widget w, String); + +static String _XawEscapeActionVarValue(String); +static String _XawUnescapeActionVarValue(String); +static XawActionResList *_XawCreateActionResList(WidgetClass); +static XawActionResList *_XawFindActionResList(WidgetClass); +static void _XawBindActionResList(XawActionResList*); +static XawActionRes *_XawFindActionRes(XawActionResList*, Widget, String); +static int qcmp_action_resource_list(_Xconst void*, _Xconst void*); +static int bcmp_action_resource_list(_Xconst void*, _Xconst void*); +static int qcmp_action_resource(_Xconst void*, _Xconst void*); +static int bcmp_action_resource(_Xconst void*, _Xconst void*); + +/* variables */ +static String XawConvertActionVar(XawActionVarList*, String); +static void XawDeclareActionVar(XawActionVarList*, String, String); + +static XawActionVarList *_XawCreateActionVarList(Widget); +static XawActionVarList *_XawFindActionVarList(Widget); +static XawActionVar *_XawCreateActionVar(XawActionVarList*, String); +static XawActionVar *_XawFindActionVar(XawActionVarList*, String); +static void _XawDestroyActionVarList(Widget, XtPointer, XtPointer); + +/* + * Initialization + */ +/* resources */ +static XawActionResList **resource_list; +static Cardinal num_resource_list; + +/* variables */ +static XawActionVarList **variable_list; +static Cardinal num_variable_list; + +/* + * Implementation + */ +/* + * Start of Boolean Expression Evaluation Implementation Code + */ +Bool +XawParseBoolean(Widget w, String param, XEvent *event, Bool *succed) +{ + char *tmp = param; + int value; + + if (!param) + return (False); + + value = (int)strtod(param, &tmp); + if (*tmp == '\0') + return (value); + + if (XmuCompareISOLatin1(param, "true") == 0 + || XmuCompareISOLatin1(param, "yes") == 0 + || XmuCompareISOLatin1(param, "on") == 0 + || XmuCompareISOLatin1(param, "in") == 0 + || XmuCompareISOLatin1(param, "up") == 0) + return (True); + else if (XmuCompareISOLatin1(param, "false") == 0 + || XmuCompareISOLatin1(param, "no") == 0 + || XmuCompareISOLatin1(param, "off") == 0 + || XmuCompareISOLatin1(param, "out") == 0 + || XmuCompareISOLatin1(param, "down") == 0) + ; + else if (XmuCompareISOLatin1(param, "my") == 0 + || XmuCompareISOLatin1(param, "mine") == 0) + return (event->xany.window == XtWindow(w)); + else if (XmuCompareISOLatin1(param, "faked") == 0) + return (event->xany.send_event != 0); + else + *succed = False; + + return (False); +} + +Bool +XawBooleanExpression(Widget w, String param, XEvent *event) +{ + XawEvalInfo info; + Bool retval; + + if (!param) + return (False); + + info.widget = w; + + info.rlist = XawGetActionResList(XtClass(w)); + info.vlist = XawGetActionVarList(w); + + /* + * Verify widget class, in case we will allow the parse proc procedure + * as a widget class element, or if we allow overriding the default + * parse boolean proc. + */ + info.parse_proc = XawParseBoolean; + + info.event = event; + info.cp = info.lp = param; + +#ifdef DIAGNOSTIC + fprintf(stderr, "(*) Parsing expression \"%s\"\n", param); +#endif + + (void)get_token(&info); + if (info.token == ERROR) + return (False); + retval = expr(&info); + + return (info.token != ERROR ? retval : False); +} + +static int +get_token(XawEvalInfo *info) +{ + int ch; + char *p, name[256]; + + info->lp = info->cp; + + /*COSTCOND*/ + while (1) /* eat white spaces */ + { + ch = *info->cp++; + if (isspace(ch)) + continue; + break; + } + + switch (ch) + { + case AND: case OR: case XOR: case NOT: case LP: case RP: + return (info->token = ch); + } + + /* It's a symbol name, resolve it. */ + if (ch == XAW_PRIV_VAR_PREFIX || isalnum(ch) || ch == '_' || ch == '\\') + { + Bool succed = True; + + p = info->cp - 1; + + while ((ch = *info->cp) && (isalnum(ch) || ch == '_')) + ++info->cp; + + strncpy(name, p, XawMin((int)sizeof(name) - 1, + (unsigned)(info->cp - p))); + name[XawMin((int)sizeof(name) -1, info->cp - p)] = '\0'; + + if (name[0] == XAW_PRIV_VAR_PREFIX) + { + String value = XawConvertActionVar(info->vlist, name); + + info->value = info->parse_proc(info->widget, value, info->event, + &succed) & 1; + } + else + { + info->value = info->parse_proc(info->widget, name, info->event, + &succed) & 1; + if (!succed) + { + String value = + XawConvertActionRes(info->rlist, info->widget, + name[0] == '\\' ? &name[1] : name); + /* '\\' may have been used to escape a resource name. + */ + + succed = True; + info->value = info->parse_proc(info->widget, value, info->event, + &succed) & 1; + if (!succed) + { + /* not a numeric value or boolean string */ + info->value = True; + succed = True; + } + } + } + if (succed) + return (info->token = BOOLEAN); + } + else if (ch == '\0') + return (info->token = END); + + { + char msg[256]; + + snprintf(msg, sizeof(msg), "evaluate(): bad token \"%c\" at \"%s\"", + ch, info->cp - 1); + + XtAppWarning(XtWidgetToApplicationContext(info->widget), msg); + } + + return (info->token = ERROR); +} + +static Bool +expr(XawEvalInfo *info) +{ + Bool left = and(info); + + for (;;) + switch (info->token) + { + case OR: + (void)get_token(info); + left |= and(info); + break; + case XOR: + (void)get_token(info); + left ^= and(info); + break; + default: + return (left); + } + /* NOTREACHED */ +} + +static Bool +and(XawEvalInfo *info) +{ + Bool left = prim(info); + + for (;;) + switch (info->token) + { + case AND: + (void)get_token(info); + left &= prim(info); + break; + default: + return (left); + } + /* NOTREACHED */ +} + +static Bool +prim(XawEvalInfo *info) +{ + Bool e; + + switch (info->token) + { + case BOOLEAN: + e = info->value; + (void)get_token(info); + return (e); + case NOT: + (void)get_token(info); + return (!prim(info)); + case LP: + (void)get_token(info); + e = expr(info); + if (info->token != RP) + { + char msg[256]; + + info->token = ERROR; + snprintf(msg, sizeof(msg), "evaluate(): expecting ), at \"%s\"", + info->lp); + XtAppWarning(XtWidgetToApplicationContext(info->widget), msg); + return (False); + } + (void)get_token(info); + return (e); + case END: + return (True); + default: + { + char msg[256]; + + info->token = ERROR; + snprintf(msg, sizeof(msg), "evaluate(): syntax error, at \"%s\"", + info->lp); + XtAppWarning(XtWidgetToApplicationContext(info->widget), msg); + } return (False); + } + /* NOTREACHED */ +} + +/* + * Start of Resources Implementation Code + */ +void +XawSetValuesAction(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + Arg *arglist; + Cardinal num_args, count; + XawActionResList *rlist; + XawActionVarList *vlist; + XawActionRes *resource; + XrmValue from, to; + String value; + char c_1; + short c_2; + int c_4; +#ifdef LONG64 + long c_8; +#endif + + if (!(*num_params & 1)) + { + XawPrintActionErrorMsg("set-values", w, params, num_params); + return; + } + + if (!XawBooleanExpression(w, params[0], event)) + return; + + rlist = XawGetActionResList(XtClass(w)); + vlist = XawGetActionVarList(w); + + num_args = 0; + arglist = (Arg *)XtMalloc(sizeof(Arg) * ((*num_params) >> 1)); + + for (count = 1; count < *num_params; count += 2) + { + if ((resource = _XawFindActionRes(rlist, w, params[count])) == NULL) + { + char msg[256]; + + snprintf(msg, sizeof(msg), "set-values(): bad resource name \"%s\"", + params[count]); + XtAppWarning(XtWidgetToApplicationContext(w), msg); + continue; + } + value = XawConvertActionVar(vlist, params[count + 1]); + from.size = strlen(value) + 1; + from.addr = value; + to.size = resource->size; + switch (to.size) + { + case 1: to.addr = (XPointer)&c_1; break; + case 2: to.addr = (XPointer)&c_2; break; + case 4: to.addr = (XPointer)&c_4; break; +#ifdef LONG64 + case 8: to.addr = (XPointer)&c_8; break; +#endif + default: + { + char msg[256]; + + snprintf(msg, sizeof(msg), + "set-values(): bad resource size for \"%s\"", + params[count]); + XtAppWarning(XtWidgetToApplicationContext(w), msg); + } continue; + } + + if (strcmp(XtRString, XrmQuarkToString(resource->qtype)) == 0) +#ifdef LONG64 + c_8 = (long)from.addr; +#else + c_4 = (int)from.addr; +#endif + else if (!XtConvertAndStore(w, XtRString, &from, + XrmQuarkToString(resource->qtype), &to)) + continue; + + switch (to.size) + { + case 1: + XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_1); + break; + case 2: + XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_2); + break; + case 4: + XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_4); + break; +#ifdef LONG64 + case 8: + XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_8); + break; +#endif + } + ++num_args; + } + + XtSetValues(w, arglist, num_args); + XtFree((char *)arglist); +} + +void +XawGetValuesAction(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + XawActionResList *rlist; + XawActionVarList *vlist; + String value; + Cardinal count; + + if (!(*num_params & 1)) + { + XawPrintActionErrorMsg("get-values", w, params, num_params); + return; + } + if (!XawBooleanExpression(w, params[0], event)) + return; + + rlist = XawGetActionResList(XtClass(w)); + vlist = XawGetActionVarList(w); + + for (count = 1; count < *num_params; count += 2) + { + if ((value = XawConvertActionRes(rlist, w, params[count + 1])) == NULL) + continue; + XawDeclareActionVar(vlist, params[count], value); + } +} + +void +XawDeclareAction(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + XawActionVarList *vlist; + Cardinal count; + + if (!(*num_params & 1)) + { + XawPrintActionErrorMsg("declare", w, params, num_params); + return; + } + if (!XawBooleanExpression(w, params[0], event)) + return; + + vlist = XawGetActionVarList(w); + + for (count = 1; count < *num_params; count += 2) + XawDeclareActionVar(vlist, params[count], params[count + 1]); +} + +void +XawCallProcAction(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + String *args; + Cardinal num_args; + + if (*num_params < 2) + { + XawPrintActionErrorMsg("call-proc", w, params, num_params); + return; + } + + if (*num_params && !XawBooleanExpression(w, params[0], event)) + return; + + if (*num_params > 2) + { + args = ¶ms[2]; + num_args = *num_params - 2; + } + else + { + args = NULL; + num_args = 0; + } + + XtCallActionProc(w, params[1], event, args, num_args); +} + +static String +XawConvertActionRes(XawActionResList *list, Widget w, String name) +{ + XawActionRes *resource; + XrmValue from, to; + Arg arg; + char c_1; + short c_2; + int c_4; +#ifdef LONG64 + long c_8; +#endif + + if ((resource = _XawFindActionRes(list, w, name)) == NULL) + { + char msg[256]; + + snprintf(msg, sizeof(msg), "convert(): bad resource name \"%s\"", + name); + XtAppWarning(XtWidgetToApplicationContext(w), msg); + return (NULL); + } + + from.size = resource->size; + switch (from.size) + { + case 1: + XtSetArg(arg, XrmQuarkToString(resource->qname), + from.addr = (XPointer)&c_1); + break; + case 2: + XtSetArg(arg, XrmQuarkToString(resource->qname), + from.addr = (XPointer)&c_2); + break; + case 4: + XtSetArg(arg, XrmQuarkToString(resource->qname), + from.addr = (XPointer)&c_4); + break; +#ifdef LONG64 + case 8: + XtSetArg(arg, XrmQuarkToString(resource->qname), + from.addr = (XPointer)&c_8); + break; +#endif + default: + { + char msg[256]; + + snprintf(msg, sizeof(msg), "convert(): bad resource size for \"%s\"", + name); + XtAppWarning(XtWidgetToApplicationContext(w), name); + } return (NULL); + } + + XtGetValues(w, &arg, 1); + to.size = sizeof(String); + to.addr = NULL; + + if (strcmp(XtRString, XrmQuarkToString(resource->qtype)) == 0) + to.addr = *(char **)from.addr; + else if (!XtConvertAndStore(w, XrmQuarkToString(resource->qtype), + &from, XtRString, &to)) + return (NULL); + + return ((String)to.addr); +} + +void +XawPrintActionErrorMsg(String action_name, Widget w, + String *params, Cardinal *num_params) +{ + char msg[1024]; + unsigned int size, idx; + + size = snprintf(msg, sizeof(msg), "%s(): bad number of parameters.\n\t(", + action_name); + + idx = 0; + while (idx < *num_params - 1 && size < sizeof(msg)) + size += snprintf(&msg[size], sizeof(msg) - size, "%s, ", + params[idx++]); + if (*num_params) + snprintf(&msg[size], sizeof(msg) - size, "%s)", params[idx]); + else + snprintf(&msg[size], sizeof(msg) - size, ")"); + XtAppWarning(XtWidgetToApplicationContext(w), msg); +} + +XawActionResList * +XawGetActionResList(WidgetClass wc) +{ + XawActionResList *list; + + list = _XawFindActionResList(wc); + + if (!list) + list = _XawCreateActionResList(wc); + + return (list); +} + +static int +qcmp_action_resource_list(register _Xconst void *left, + register _Xconst void *right) +{ + return ((char *)((*(XawActionResList **)left)->widget_class) - + (char *)((*(XawActionResList **)right)->widget_class)); +} + +static XawActionResList * +_XawCreateActionResList(WidgetClass wc) +{ + XawActionResList *list; + + list = (XawActionResList *)XtMalloc(sizeof(XawActionResList)); + list->widget_class = wc; + list->num_common_resources = list->num_constraint_resources = 0; + list->resources = NULL; + + if (!resource_list) + { + num_resource_list = 1; + resource_list = (XawActionResList **)XtMalloc(sizeof(XawActionResList*)); + resource_list[0] = list; + } + else + { + ++num_resource_list; + resource_list = (XawActionResList **)XtRealloc((char *)resource_list, + sizeof(XawActionResList*) + * num_resource_list); + resource_list[num_resource_list - 1] = list; + qsort(resource_list, num_resource_list, sizeof(XawActionResList*), + qcmp_action_resource_list); + } + + _XawBindActionResList(list); + + return (list); +} + +static int +bcmp_action_resource_list(register _Xconst void *wc, + register _Xconst void *list) +{ + return ((char *)wc - (char *)((*(XawActionResList **)list)->widget_class)); +} + +static XawActionResList * +_XawFindActionResList(WidgetClass wc) +{ + XawActionResList **list; + + if (!resource_list) + return (NULL); + + list = (XawActionResList **)bsearch(wc, resource_list, + num_resource_list, + sizeof(XawActionResList*), + bcmp_action_resource_list); + + return (list ? *list : NULL); +} + +static int +qcmp_action_resource(register _Xconst void *left, + register _Xconst void *right) +{ + return (strcmp(XrmQuarkToString((*(XawActionRes **)left)->qname), + XrmQuarkToString((*(XawActionRes **)right)->qname))); +} + +static void +_XawBindActionResList(XawActionResList *list) +{ + XtResourceList xt_list, cons_list; + Cardinal i, num_xt, num_cons; + +#ifdef DIAGNOSTIC + fprintf(stderr, "(*) Creating resource list for class \'%s\'\n---------\n", + list->widget_class->core_class.class_name); +#endif + + XtGetResourceList(list->widget_class, &xt_list, &num_xt); + XtGetConstraintResourceList(list->widget_class, &cons_list, &num_cons); + list->num_common_resources = num_xt; + list->num_constraint_resources = num_cons; + + list->resources = (XawActionRes **) + XtMalloc(sizeof(XawActionRes*) * (num_xt + num_cons)); + +#ifdef DIAGNOSTIC + fprintf(stderr, "Common resources\n---\n"); +#endif + + for (i = 0; i < num_xt; i++) + { + list->resources[i] = (XawActionRes *)XtMalloc(sizeof(XawActionRes)); + list->resources[i]->qname = + XrmPermStringToQuark(xt_list[i].resource_name); + list->resources[i]->qtype = + XrmPermStringToQuark(xt_list[i].resource_type); + list->resources[i]->size = xt_list[i].resource_size; + +#ifdef DIAGNOSTIC + fprintf(stderr, "%-20s\t%-20s\t(%d)\n", + xt_list[i].resource_name, + xt_list[i].resource_type, + xt_list[i].resource_size); +#endif + } + +#ifdef DIAGNOSTIC + fprintf(stderr, "---\nContraint resources\n---"); +#endif + + for (; i < num_xt + num_cons; i++) + { + list->resources[i] = (XawActionRes *)XtMalloc(sizeof(XawActionRes)); + list->resources[i]->qname = + XrmPermStringToQuark(cons_list[i - num_xt].resource_name); + list->resources[i]->qtype = + XrmPermStringToQuark(cons_list[i - num_xt].resource_type); + list->resources[i]->size = cons_list[i - num_xt].resource_size; + +#ifdef DIAGNOSTIC + fprintf(stderr, "%-20s\t%-20s\t(%d)\n", + cons_list[i - num_xt].resource_name, + cons_list[i - num_xt].resource_type, + cons_list[i - num_xt].resource_size); +#endif + } + +#ifdef DIAGNOSTIC + fprintf(stderr, "---\n"); +#endif + + XtFree((char *)xt_list); + if (cons_list) + XtFree((char *)cons_list); + + qsort(list->resources, list->num_common_resources, sizeof(XawActionRes*), + qcmp_action_resource); + if (num_cons) + qsort(&list->resources[num_xt], list->num_constraint_resources, + sizeof(XawActionRes*), qcmp_action_resource); +} + +static int +bcmp_action_resource(register _Xconst void *string, + register _Xconst void *resource) +{ + return (strcmp((String)string, + XrmQuarkToString((*(XawActionRes **)resource)->qname))); +} + +static XawActionRes * +_XawFindActionRes(XawActionResList *list, Widget detail, String name) +{ + XawActionRes **res; + + if (!list->resources) + return (NULL); + + res = (XawActionRes **)bsearch(name, list->resources, + list->num_common_resources, + sizeof(XawActionRes*), bcmp_action_resource); + + if (!res && XtParent(detail) + && XtIsSubclass(XtParent(detail), constraintWidgetClass)) + { + XawActionResList *cons = XawGetActionResList(XtClass(XtParent(detail))); + + if (cons) + res = (XawActionRes **) + bsearch(name, &cons->resources[cons->num_common_resources], + cons->num_constraint_resources, + sizeof(XawActionRes*), bcmp_action_resource); + } + + return (res ? *res : NULL); +} + +/* + * Start of Variables Implementation Code + */ +/* For speed, only does memory allocation when really required */ +static String +_XawEscapeActionVarValue(String value) +{ + String escape; + + if (value[0] == '$' || value[0] == '\\') + { + escape = XtMalloc(strlen(value) + 2); + escape[0] = '\\'; + strcpy(escape + 1, value); + return (escape); + } + return (NULL); +} + +/* For speed, only does memory allocation when really required */ +static String +_XawUnescapeActionVarValue(String value) +{ + String unescape; + + if (value[0] == '\\') + { + unescape = XtMalloc(strlen(value)); + strcpy(unescape, value + 1); + return (unescape); + } + return (NULL); +} + +static void +XawDeclareActionVar(XawActionVarList *list, String name, String value) +{ + XawActionVar *variable; + String escape = NULL; + + if (name[0] != XAW_PRIV_VAR_PREFIX) + { + char msg[256]; + + snprintf(msg, sizeof(msg), + "declare(): variable name must begin with \'%c\', at %s = %s", + XAW_PRIV_VAR_PREFIX, name, value); + XtAppWarning(XtWidgetToApplicationContext(list->widget), msg); + return; + } + variable = _XawFindActionVar(list, name); + if (!variable) + variable = _XawCreateActionVar(list, name); + if (value) + escape = _XawEscapeActionVarValue(value); + + if (variable->qvalue) + { + String val = escape ? escape : value; + + if (strcmp(XrmQuarkToString(variable->qvalue), val) == 0) + { + if (escape) + XtFree(escape); + return; + } + } + variable->qvalue = (escape ? XrmStringToQuark(escape) : + (value ? XrmStringToQuark(value) : NULLQUARK)); + if (escape) + XtFree(escape); +} + +static String +XawConvertActionVar(XawActionVarList *list, String name) +{ + XawActionVar *variable; + String unescape; + XrmQuark quark; + + if (name[0] != XAW_PRIV_VAR_PREFIX) + return (name); + + variable = _XawFindActionVar(list, name); + if (!variable || variable->qvalue == NULLQUARK) + return (name); + unescape = _XawUnescapeActionVarValue(XrmQuarkToString(variable->qvalue)); + if (unescape) + { + quark = XrmStringToQuark(unescape); + XtFree(unescape); + } + else + quark = variable->qvalue; + + return (XrmQuarkToString(quark)); +} + +XawActionVarList * +XawGetActionVarList(Widget w) +{ + XawActionVarList *list; + + list = _XawFindActionVarList(w); + if (!list) + list = _XawCreateActionVarList(w); + + return (list); +} + +static int +qcmp_action_variable_list(register _Xconst void *left, + register _Xconst void *right) +{ + return ((char *)((*(XawActionVarList **)left)->widget) - + (char *)((*(XawActionVarList **)right)->widget)); +} + +static XawActionVarList * +_XawCreateActionVarList(Widget w) +{ + XawActionVarList *list; + +#ifdef DIAGNOSTIC + fprintf(stderr, "(*) Creating action variable list for widget %s (%p)\n", + XtName(w), w); +#endif + + list = (XawActionVarList *)XtMalloc(sizeof(XawActionVarList)); + list->widget = w; + list->num_variables = 0; + list->variables = NULL; + + if (!variable_list) + { + num_variable_list = 1; + variable_list = (XawActionVarList **)XtMalloc(sizeof(XawActionVarList*)); + variable_list[0] = list; + } + else + { + ++num_variable_list; + variable_list = (XawActionVarList **) + XtRealloc((char *)variable_list, + sizeof(XawActionVarList *) * num_variable_list); + variable_list[num_variable_list - 1] = list; + qsort(variable_list, num_variable_list, sizeof(XawActionVarList*), + qcmp_action_variable_list); + } + + XtAddCallback(w, XtNdestroyCallback, _XawDestroyActionVarList, + (XtPointer)list); + + return (list); +} + +static int +bcmp_action_variable_list(register _Xconst void *widget, + register _Xconst void *list) +{ + return ((char *)widget - (char *)((*(XawActionVarList **)list)->widget)); +} + +static XawActionVarList * +_XawFindActionVarList(Widget w) +{ + XawActionVarList **list; + + if (!num_variable_list) + return (NULL); + + list = (XawActionVarList **)bsearch(w, variable_list, num_variable_list, + sizeof(XawActionVarList*), + bcmp_action_variable_list); + + return (list ? *list : NULL); +} + +static int +qcmp_action_variable(register _Xconst void *left, + register _Xconst void *right) +{ + return (strcmp(XrmQuarkToString((*(XawActionVar **)left)->qname), + XrmQuarkToString((*(XawActionVar **)right)->qname))); +} + +static XawActionVar * +_XawCreateActionVar(XawActionVarList *list, String name) +{ + XawActionVar *variable; + +#ifdef DIAGNOSTIC + fprintf(stderr, "(*) Creating action variable '%s' for widget %s (%p)\n", + name, XtName(list->widget), list->widget); +#endif + + variable = (XawActionVar *)XtMalloc(sizeof(XawActionVar)); + variable->qname = XrmStringToQuark(name); + variable->qvalue = NULLQUARK; + + if (!list->variables) + { + list->num_variables = 1; + list->variables = (XawActionVar **)XtMalloc(sizeof(XawActionVar*)); + list->variables[0] = variable; + } + else + { + ++list->num_variables; + list->variables = (XawActionVar **)XtRealloc((char *)list->variables, + sizeof(XawActionVar *) * + list->num_variables); + list->variables[list->num_variables - 1] = variable; + qsort(list->variables, list->num_variables, sizeof(XawActionVar*), + qcmp_action_variable); + } + return (variable); +} + +static int +bcmp_action_variable(register _Xconst void *string, + register _Xconst void *variable) +{ + return (strcmp((String)string, + XrmQuarkToString((*(XawActionVar **)variable)->qname))); +} + +static XawActionVar * +_XawFindActionVar(XawActionVarList *list, String name) +{ + XawActionVar **var; + + if (!list->variables) + return (NULL); + + var = (XawActionVar **)bsearch(name, list->variables, list->num_variables, + sizeof(XawActionVar*), bcmp_action_variable); + + return (var ? *var : NULL); +} + +/*ARGSUSED*/ +static void +_XawDestroyActionVarList(Widget w, XtPointer client_data, XtPointer call_data) +{ + XawActionVarList *list = (XawActionVarList *)client_data; + Cardinal i; + + for (i = 0; i < num_variable_list; i++) + if (variable_list[i] == list) + break; + if (i >= num_variable_list || list->widget != w + || variable_list[i]->widget != w) + { + XtWarning("destroy-variable-list(): Bad widget argument."); + return; + } + if (--num_variable_list > 0) + { + memmove(&variable_list[i], &variable_list[i + 1], + (num_variable_list - i) * sizeof(XawActionVarList *)); + variable_list = (XawActionVarList **) + XtRealloc((char *)variable_list, sizeof(XawActionVarList *) * + num_variable_list); + } + else + { + XtFree((char *)variable_list); + variable_list = NULL; + } + + XtFree((char *)list->variables); + XtFree((char *)list); +} + +#endif /* OLDXAW */ diff --git a/src/AllWidgets.c b/src/AllWidgets.c new file mode 100644 index 0000000..3b13438 --- /dev/null +++ b/src/AllWidgets.c @@ -0,0 +1,109 @@ +/* + +Copyright (c) 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +XmuWidgetNode XawWidgetArray[] = { +{ "applicationShell", &applicationShellWidgetClass }, +{ "asciiSink", &asciiSinkObjectClass }, +{ "asciiSrc", &asciiSrcObjectClass }, +{ "asciiText", &asciiTextWidgetClass }, +{ "box", &boxWidgetClass }, +{ "command", &commandWidgetClass }, +{ "composite", &compositeWidgetClass }, +{ "constraint", &constraintWidgetClass }, +{ "core", &coreWidgetClass }, +{ "dialog", &dialogWidgetClass }, +{ "form", &formWidgetClass }, +{ "grip", &gripWidgetClass }, +{ "label", &labelWidgetClass }, +{ "list", &listWidgetClass }, +{ "menuButton", &menuButtonWidgetClass }, +{ "multiSink", &multiSinkObjectClass }, +{ "multiSrc", &multiSrcObjectClass }, +{ "object", &objectClass }, +{ "overrideShell", &overrideShellWidgetClass }, +{ "paned", &panedWidgetClass }, +{ "panner", &pannerWidgetClass }, +{ "porthole", &portholeWidgetClass }, +{ "rect", &rectObjClass }, +{ "repeater", &repeaterWidgetClass }, +{ "scrollbar", &scrollbarWidgetClass }, +{ "shell", &shellWidgetClass }, +{ "simpleMenu", &simpleMenuWidgetClass }, +{ "simple", &simpleWidgetClass }, +{ "smeBSB", &smeBSBObjectClass }, +{ "smeLine", &smeLineObjectClass }, +{ "sme", &smeObjectClass }, +{ "stripChart", &stripChartWidgetClass }, +{ "textSink", &textSinkObjectClass }, +{ "textSrc", &textSrcObjectClass }, +{ "text", &textWidgetClass }, +{ "toggle", &toggleWidgetClass }, +{ "topLevelShell", &topLevelShellWidgetClass }, +{ "transientShell", &transientShellWidgetClass }, +{ "tree", &treeWidgetClass }, +{ "vendorShell", &vendorShellWidgetClass }, +{ "viewport", &viewportWidgetClass }, +{ "wmShell", &wmShellWidgetClass }, +}; + +int XawWidgetCount = XtNumber(XawWidgetArray); + diff --git a/src/AsciiSink.c b/src/AsciiSink.c new file mode 100644 index 0000000..d776895 --- /dev/null +++ b/src/AsciiSink.c @@ -0,0 +1,1948 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#ifdef GETLASTPOS +#undef GETLASTPOS /* We will use our own GETLASTPOS */ +#endif + +#define GETLASTPOS \ + XawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, True) + +/* + * Class Methods + */ +static void XawAsciiSinkClassPartInitialize(WidgetClass); +static void XawAsciiSinkInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawAsciiSinkDestroy(Widget); +static void XawAsciiSinkResize(Widget); +static Boolean XawAsciiSinkSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static int MaxLines(Widget, unsigned int); +static int MaxHeight(Widget, int); +static void SetTabs(Widget, int, short*); +static void DisplayText(Widget, int, int, + XawTextPosition, XawTextPosition, Bool); +static void InsertCursor(Widget, int, int, XawTextInsertState); +static void FindPosition(Widget, XawTextPosition, int, int, Bool, + XawTextPosition*, int*, int*); +static void FindDistance(Widget, XawTextPosition, int, XawTextPosition, int*, + XawTextPosition*, int*); +static void Resolve(Widget, XawTextPosition, int, int, XawTextPosition*); +static void GetCursorBounds(Widget, XRectangle*); +#ifndef OLDXAW +static void AsciiPreparePaint(Widget, int, int, + XawTextPosition, XawTextPosition, Bool); +static void AsciiDoPaint(Widget); +#endif + +/* + * Prototypes + */ +static void GetGC(AsciiSinkObject); +static int CharWidth(AsciiSinkObject, XFontStruct*, int, unsigned int); +static unsigned int PaintText(Widget w, GC gc, int x, int y, + char *buf, int len, Bool); + +/* + * Defined in TextSink.c + */ +void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(AsciiSinkRec, ascii_sink.field) +static XtResource resources[] = { + { + XtNfont, + XtCFont, + XtRFontStruct, + sizeof(XFontStruct*), + offset(font), + XtRString, + XtDefaultFont + }, + { + XtNecho, + XtCOutput, + XtRBoolean, + sizeof(Boolean), + offset(echo), + XtRImmediate, + (XtPointer)True + }, + { + XtNdisplayNonprinting, + XtCOutput, + XtRBoolean, + sizeof(Boolean), + offset(display_nonprinting), + XtRImmediate, + (XtPointer) + True + }, +}; +#undef offset + +#define Superclass (&textSinkClassRec) +AsciiSinkClassRec asciiSinkClassRec = { + /* object */ + { + (WidgetClass)Superclass, /* superclass */ + "AsciiSink", /* class_name */ + sizeof(AsciiSinkRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + XawAsciiSinkClassPartInitialize, /* class_part_initialize */ + False, /* class_inited */ + XawAsciiSinkInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* obj1 */ + NULL, /* obj2 */ + 0, /* obj3 */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* obj4 */ + False, /* obj5 */ + False, /* obj6 */ + False, /* obj7 */ + XawAsciiSinkDestroy, /* destroy */ + (XtProc)XawAsciiSinkResize, /* obj8 */ + NULL, /* obj9 */ + XawAsciiSinkSetValues, /* set_values */ + NULL, /* set_values_hook */ + NULL, /* obj10 */ + NULL, /* get_values_hook */ + NULL, /* obj11 */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* obj12 */ + NULL, /* obj13 */ + NULL, /* obj14 */ + NULL, /* extension */ + }, + /* text_sink */ + { + DisplayText, /* DisplayText */ + InsertCursor, /* InsertCursor */ + XtInheritClearToBackground, /* ClearToBackground */ + FindPosition, /* FindPosition */ + FindDistance, /* FindDistance */ + Resolve, /* Resolve */ + MaxLines, /* MaxLines */ + MaxHeight, /* MaxHeight */ + SetTabs, /* SetTabs */ + GetCursorBounds, /* GetCursorBounds */ +#ifndef OLDXAW + NULL /* extension */ +#endif + }, + /* ascii_sink */ + { + NULL, /* extension */ + } +}; + +WidgetClass asciiSinkObjectClass = (WidgetClass)&asciiSinkClassRec; + +/* + * Implementation + */ +static void +XawAsciiSinkClassPartInitialize(WidgetClass wc) +{ +#ifndef OLDXAW + AsciiSinkObjectClass cclass = (AsciiSinkObjectClass)wc; + XrmQuark record_type = XrmPermStringToQuark("TextSink"); + TextSinkExt ext = cclass->text_sink_class.extension; + + while (ext) { + if (ext->record_type == record_type && + ext->version == 1) { + ext->PreparePaint = AsciiPreparePaint; + ext->DoPaint = AsciiDoPaint; + break; + } + ext = (TextSinkExt)ext->next_extension; + } + if (ext == NULL) + XtError("TextSinkClass: cannot resolve extension.\n"); +#endif +} + +static int +CharWidth(AsciiSinkObject sink, XFontStruct *font, int x, unsigned int c) +{ + int width = 0; + + if (c == XawLF) + return (0); + + if (c == XawTAB) { + int i; + Position *tab; + + width = x; + /* Adjust for Left Margin */ + x -= ((TextWidget)XtParent((Widget)sink))->text.left_margin; + + i = 0; + tab = sink->text_sink.tabs; + /*CONSTCOND*/ + while (1) { + if (x >= 0 && x < *tab) + return (*tab - x); + /* Start again */ + if (++i >= sink->text_sink.tab_count) { + x -= *tab; + i = 0; + tab = sink->text_sink.tabs; + if (width == x) + return (0); + } + else + ++tab; + } + /*NOTREACHED*/ + } + + if ((c & 0177) < XawSP || c == 0177) { + if (sink->ascii_sink.display_nonprinting) { + if (c > 0177) { + width = CharWidth(sink, font, x, '\\'); + width += CharWidth(sink, font, x, ((c >> 6) & 7) + '0'); + width += CharWidth(sink, font, x, ((c >> 3) & 7) + '0'); + c = (c & 7) + '0'; + } + else { + width = CharWidth(sink, font, x, '^'); + if ((c |= 0100) == 0177) + c = '?'; + } + } + else + c = XawSP; + } + + if (font->per_char + && (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2)) + width += font->per_char[c - font->min_char_or_byte2].width; + else + width += font->min_bounds.width; + + return (width); +} + +#ifndef OLDXAW +static int +GetTextWidth(TextWidget ctx, int current_width, XFontStruct *font, + XawTextPosition from, int length) +{ + int i, width = 0; + XawTextBlock block; + XawTextPosition pos = from; + + while (length > 0) { + pos = XawTextSourceRead(ctx->text.source, from, &block, length); + length -= pos - from; + from = pos; + for (i = 0; i < block.length; i++) + width += CharWidth((AsciiSinkObject)ctx->text.sink, font, + current_width + width, + (unsigned char)block.ptr[i]); + } + + return (width); +} + +static +void CalculateBearing(TextWidget ctx, XawTextPosition position, int x, int y, + int ascent, int descent, Bool highlight, Bool right) +{ +/* + * Sample case: + * + * lbearing| width |rbearing + * | | + * | #### + * | ### | + * | #### | + * | #### | + * | ########## | + * | #### | + * | #### | + * | #### | + * | #### | + * |### | + * #### | + * | | + * + */ + AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink; + XawTextAnchor *anchor; + XawTextEntity *entity; + XawTextProperty *property; + XawTextPaintStruct *paint; + XawTextBlock block; + XFontStruct *font; + + property = NULL; + if (XawTextSourceAnchorAndEntity(ctx->text.source, position, + &anchor, &entity) && + (property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + font = property->font; + else + font = sink->ascii_sink.font; + if (right) { + if (font->max_bounds.rbearing > 0) { + int rbearing = font->max_bounds.rbearing - font->max_bounds.width; + unsigned char c; + + (void)XawTextSourceRead(ctx->text.source, position, &block, 1); + c = *(unsigned char*)block.ptr; + if (c == '\t' || c == '\n') + c = ' '; + else if ((c & 0177) < XawSP || c == 0177) { + if (sink->ascii_sink.display_nonprinting) + c = c > 0177 ? (c & 7) + '0' : c + '@'; + else + c = ' '; + } + if (font->per_char && + (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2)) + rbearing = font->per_char[c - font->min_char_or_byte2].rbearing - + font->per_char[c - font->min_char_or_byte2].width; + if (rbearing > 0) { + paint = XtNew(XawTextPaintStruct); + paint->next = sink->text_sink.paint->bearings; + sink->text_sink.paint->bearings = paint; + paint->x = x - (paint->width = CharWidth(sink, font, 0, c)); + paint->y = y + ascent; + paint->property = property; + paint->max_ascent = ascent; + paint->max_descent = descent; + paint->backtabs = NULL; + paint->highlight = highlight; + paint->length = 1; + paint->text = XtMalloc(1); + paint->text[0] = c; + } + } + } + else { + if (font->min_bounds.lbearing < 0) { + int lbearing = font->min_bounds.lbearing; + unsigned char c; + + (void)XawTextSourceRead(ctx->text.source, position, &block, 1); + c = *(unsigned char*)block.ptr; + if (c == '\t' || c == '\n') + c = ' '; + else if ((c & 0177) < XawSP || c == 0177) { + if (sink->ascii_sink.display_nonprinting) + c = c > 0177 ? '\\' : c + '^'; + else + c = ' '; + } + if (font->per_char && + (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2)) + lbearing = font->per_char[c - font->min_char_or_byte2].lbearing; + if (lbearing < 0) { + paint = XtNew(XawTextPaintStruct); + paint->next = sink->text_sink.paint->bearings; + sink->text_sink.paint->bearings = paint; + paint->x = x; + paint->width = -CharWidth(sink, font, 0, c); + paint->y = y + ascent; + paint->property = property; + paint->max_ascent = ascent; + paint->max_descent = descent; + paint->backtabs = NULL; + paint->highlight = highlight; + paint->length = 1; + paint->text = XtMalloc(1); + paint->text[0] = c; + } + } + } +} + +static void +AsciiPreparePaint(Widget w, int y, int line, + XawTextPosition from, XawTextPosition to, Bool highlight) +{ + static XmuSegment segment; + static XmuScanline next; + static XmuScanline scanline = {0, &segment, &next}; + static XmuArea area = {&scanline}; + + TextWidget ctx = (TextWidget)XtParent(w); + AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink; + XawTextPosition left, right, pos, pos2, tmp, length; + XawTextAnchor *anchor; + XawTextEntity *entity; + XawTextProperty *property; + int i, ascent = 0, descent = 0, xl, xr, x = ctx->text.left_margin, bufsiz; + XawTextBlock block; + XFontStruct *font; + XawTextPaintStruct *paint; + + if (!sink->ascii_sink.echo) + return; + + /* pass 1: calculate ascent/descent values and x coordinate */ + /* XXX the MAX ascent/descent value should be in the line table XXX */ + /* XXX the x coordinate can be a parameter, but since it is required + to calculate the ascent/descent, do it here to avoid an extra + search in the entities */ + pos = tmp = left = ctx->text.lt.info[line].position; + right = ctx->text.lt.info[line + 1].position; + right = XawMin(right, ctx->text.lastPos + 1); + while (pos < right) { + if (XawTextSourceAnchorAndEntity(ctx->text.source, pos, + &anchor, &entity)) { + if ((property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + font = property->font; + else + font = sink->ascii_sink.font; + tmp = pos; + pos = anchor->position + entity->offset + entity->length; + if ((length = XawMin(from, pos) - tmp) > 0) + x += GetTextWidth(ctx, x, font, tmp, length); + ascent = XawMax(font->ascent, ascent); + descent = XawMax(font->descent, descent); + } + else if (anchor) { + ascent = XawMax(sink->ascii_sink.font->ascent, ascent); + descent = XawMax(sink->ascii_sink.font->descent, descent); + while (entity && pos < right) { + tmp = pos; + if ((pos = anchor->position + entity->offset) < tmp) + pos = tmp; + else { + if ((length = XawMin(from, pos) - tmp) > 0) { + x += GetTextWidth(ctx, x, sink->ascii_sink.font, tmp, + length); + tmp += length; + } + if (pos < right) { + pos += entity->length; + if ((property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + font = property->font; + else + font = sink->ascii_sink.font; + if ((length = XawMin(from, pos) - tmp) > 0) + x += GetTextWidth(ctx, x, font, tmp, length); + ascent = XawMax(font->ascent, ascent); + descent = XawMax(font->descent, descent); + } + } + entity = entity->next; + } + + if (anchor->entities == NULL) { + tmp = XawMin(pos, from); + if ((length = from - tmp) > 0) + x += GetTextWidth(ctx, x, sink->ascii_sink.font, tmp, length); + break; + } + } + else { + tmp = XawMin(pos, from); + if ((length = from - tmp) > 0) + x += GetTextWidth(ctx, x, sink->ascii_sink.font, tmp, length); + ascent = XawMax(sink->ascii_sink.font->ascent, ascent); + descent = XawMax(sink->ascii_sink.font->descent, descent); + break; + } + } + if (!ascent) + ascent = sink->ascii_sink.font->ascent; + if (!descent) + descent = sink->ascii_sink.font->descent; + + xl = x; + + /* pass 2: feed the XawTextPaintStruct lists */ + pos = from; + while (pos < to) { + paint = XtNew(XawTextPaintStruct); + paint->next = sink->text_sink.paint->paint; + sink->text_sink.paint->paint = paint; + paint->x = x; + paint->y = y + ascent; + paint->property = NULL; + paint->max_ascent = ascent; + paint->max_descent = descent; + paint->backtabs = NULL; + paint->highlight = highlight; + + tmp = pos; + if (XawTextSourceAnchorAndEntity(ctx->text.source, pos, + &anchor, &entity)) { + pos = anchor->position + entity->offset + entity->length; + if ((paint->property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (paint->property->mask & XAW_TPROP_FONT)) + font = paint->property->font; + else + font = sink->ascii_sink.font; + } + else { + if (anchor) { + while (entity && anchor->position + entity->offset < pos) + entity = entity->next; + if (entity) + pos = anchor->position + entity->offset; + else + pos = to; + } + else + pos = to; + font = sink->ascii_sink.font; + } + pos = XawMin(pos, to); + length = pos - tmp; + + paint->text = XtMalloc(bufsiz = pos - tmp + 4); + paint->length = 0; + segment.x1 = x; + + pos2 = tmp; + while (length > 0) { + pos2 = XawTextSourceRead(ctx->text.source, tmp, &block, length); + length = pos - pos2; + tmp = pos2; + for (i = 0; i < block.length; i++) { + unsigned char c = (unsigned char)block.ptr[i]; + + if (paint->length + 4 > bufsiz) + paint->text = XtRealloc(paint->text, bufsiz += 32); + paint->text[paint->length] = c; + if (c == '\n') { + x += CharWidth(sink, font, 0, ' '); + continue; + } + if (c == '\t') { + x += XTextWidth(font, paint->text, paint->length); + segment.x2 = x + CharWidth(sink, font, x, '\t'); + + if (XmuValidSegment(&segment)) { + if (!highlight && (paint->property && + (paint->property->mask & XAW_TPROP_BACKGROUND))) { + if (ascent > font->ascent) { + scanline.y = y; + next.y = y + ascent - font->ascent; + XmuAreaOr(sink->text_sink.paint->clip, &area); + } + if (descent >= font->descent) { + scanline.y = y + ascent + font->descent; + next.y = scanline.y + descent - font->descent + 1; + XmuAreaOr(sink->text_sink.paint->clip, &area); + } + if (paint->backtabs == NULL) + paint->backtabs = XmuCreateArea(); + scanline.y = y + ascent - font->ascent; + next.y = y + ascent + font->descent; + XmuAreaOr(paint->backtabs, &area); + } + else { + scanline.y = y; + next.y = ctx->text.lt.info[line + 1].y; + if (highlight) { + if (!sink->text_sink.paint->hightabs) + sink->text_sink.paint->hightabs = + XmuCreateArea(); + XmuAreaOr(sink->text_sink.paint->hightabs, &area); + } + else + XmuAreaOr(sink->text_sink.paint->clip, &area); + } + } + + paint->width = segment.x2 - segment.x1; + x = segment.x1 = segment.x2; + + if (paint->length == 0) { + paint->x = x; + continue; + } + paint->text = XtRealloc(paint->text, paint->length); + property = paint->property; + paint = XtNew(XawTextPaintStruct); + paint->next = sink->text_sink.paint->paint; + sink->text_sink.paint->paint = paint; + paint->x = x; + paint->y = y + ascent; + paint->property = property; + paint->max_ascent = ascent; + paint->max_descent = descent; + paint->backtabs = NULL; + paint->highlight = highlight; + paint->text = XtMalloc(bufsiz = pos - tmp - length + + block.length - i + 4); + paint->length = 0; + continue; + } + if ((c & 0177) < XawSP || c == 0177) { + if (sink->ascii_sink.display_nonprinting) { + if (c > 0177) { + paint->text[paint->length++] = '\\'; + paint->text[paint->length++] = ((c >> 6) & 7) + '0'; + paint->text[paint->length++] = ((c >> 3) & 7) + '0'; + paint->text[paint->length] = (c & 7) + '0'; + } + else { + c |= 0100; + paint->text[paint->length++] = '^'; + paint->text[paint->length] = c == 0177 ? '?' : c; + } + } + else + paint->text[paint->length] = ' '; + } + paint->length++; + } + } + + x += XTextWidth(font, paint->text, paint->length); + segment.x2 = x; + if (XmuValidSegment(&segment)) { + /* erase only what really is needed */ + /*if (!highlight || (paint->property && + (paint->property->mask & XAW_TPROP_BACKGROUND))) { + if (ascent > font->ascent) { + scanline.y = y; + next.y = y + ascent - font->ascent; + XmuAreaOr(sink->text_sink.paint->clip, &area); + } + if (descent > font->descent) { + scanline.y = y + ascent + font->descent; + next.y = scanline.y + descent - font->descent; + XmuAreaOr(sink->text_sink.paint->clip, &area); + } + } + else*/ { + scanline.y = y; + next.y = ctx->text.lt.info[line + 1].y; + XmuAreaOr(sink->text_sink.paint->clip, &area); + } + } + + paint->width = x - segment.x1; + } + + xr = x; + + /* pass 3: bearing clipping */ + if (left < from) { + CalculateBearing(ctx, from - 1, xl, y, ascent, descent, highlight, True); + if (ctx->text.s.left < ctx->text.s.right) { + if (ctx->text.s.right == from) + CalculateBearing(ctx, from, xl, y, ascent, descent, True, False); + else if (ctx->text.s.left == from) + CalculateBearing(ctx, from, xl, y, ascent, descent, False, False); + } + } + right = XawMin(right, ctx->text.lastPos); + if (right >= to && to > from) { + if (to < right) + CalculateBearing(ctx, to, xr, y, ascent, descent, highlight, False); + if (ctx->text.s.left < ctx->text.s.right) { + if (ctx->text.s.right == to) + CalculateBearing(ctx, to - 1, xr, y, ascent, descent, False, True); + else if (ctx->text.s.left == to) + CalculateBearing(ctx, to - 1, xr, y, ascent, descent, True, True); + } + } +} + +static int +qcmp_paint_struct(_Xconst void *left, _Xconst void *right) +{ + return ((*(XawTextPaintStruct**)left)->property - + (*(XawTextPaintStruct**)right)->property); +} + +static void +AsciiDoPaint(Widget w) +{ + TextWidget ctx = (TextWidget)XtParent(w); + AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink; + XmuScanline *scan; + XmuSegment *seg; + XawTextPaintList *list = sink->text_sink.paint; +#if 0 + XawTextPaintStruct *base, *head; +#endif + XawTextPaintStruct *paint = list->paint; + XawTextProperty *property; + XFontStruct *font = NULL; + XRectangle *rects; + int n_rects, i_rects; + GC gc; + Bool highlight; + XRectangle rect; + int width, height, line_width = -1; + XGCValues values; + + /* pass 1: clear clipping areas */ + /* XXX Don't use XDrawImageString because the font may be italic, and + will get incorrectly drawn. Probably, it could be a good idea to + check if this is the case, and do special processing. But this + will need to be checked if required. */ + for (scan = list->clip->scanline; scan && scan->next; scan = scan->next) + for (seg = scan->segment; seg; seg = seg->next) + _XawTextSinkClearToBackground(ctx->text.sink, + seg->x1, scan->y, + seg->x2 - seg->x1, + scan->next->y - scan->y); + + /* pass 2: optimize drawing list to avoid too much GC change requests */ + /* XXX this assumes there will not exist entities drawn over other + entities. */ +#if 0 + while (paint) { + base = paint; + head = paint->next; + while (head) { + if (head->property == paint->property) { + base->next = head->next; + head->next = paint->next; + paint->next = head; + paint = head; + } + base = head; + head = head->next; + } + paint = paint->next; + } +#endif + if (paint && paint->next) { + XawTextPaintStruct **paints; + int i = 0, n_paints = 0; + + while (paint) { + paint = paint->next; + ++n_paints; + } + paints = (XawTextPaintStruct**) + XtMalloc(n_paints * sizeof(XawTextPaintStruct)); + paint = list->paint; + while (paint) { + paints[i++] = paint; + paint = paint->next; + } + qsort((void*)paints, n_paints, sizeof(XawTextPaintStruct*), + qcmp_paint_struct); + list->paint = paints[0]; + for (i = 0; i < n_paints - 1; i++) + paints[i]->next = paints[i + 1]; + paints[i]->next = NULL; + XtFree((XtPointer)paints); + } + + /* pass 3: clip gc */ + gc = sink->ascii_sink.normgc; + + rect.x = ctx->text.r_margin.left; + rect.y = ctx->text.r_margin.top; + width = (int)XtWidth(ctx) - RHMargins(ctx); + height = (int)XtHeight(ctx) - RVMargins(ctx); + rect.width = width; + rect.height = height; + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), gc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), gc, None); + + /* pass 4: draw backgrounds */ + paint = list->paint; + property = NULL; + rects = NULL; + i_rects = n_rects = 0; + while (paint) { + if (paint->property && (paint->property->mask & XAW_TPROP_BACKGROUND)) { + if (property != paint->property) { + if (i_rects) + XFillRectangles(XtDisplay(ctx), XtWindow(ctx), gc, + rects, i_rects); + i_rects = 0; + property = paint->property; + if (property->mask & XAW_TPROP_FONT) + font = property->font; + else + font = sink->ascii_sink.font; + XSetForeground(XtDisplay(ctx), gc, property->background); + } + if (i_rects <= n_rects) + rects = (XRectangle*) + XtRealloc((XtPointer)rects, sizeof(XRectangle) * + ++n_rects); + rects[i_rects].x = paint->x; + rects[i_rects].y = paint->y - font->ascent; + rects[i_rects].width = paint->width; + rects[i_rects++].height = font->ascent + font->descent; + + if (paint->backtabs) { + for (scan = paint->backtabs->scanline; scan && scan->next; + scan = scan->next) + for (seg = scan->segment; seg; seg = seg->next) { + if (i_rects <= n_rects) + rects = (XRectangle*) + XtRealloc((XtPointer)rects, sizeof(XRectangle) * + ++n_rects); + rects[i_rects].x = seg->x1; + rects[i_rects].y = scan->y; + rects[i_rects].width = seg->x2 - seg->x1; + rects[i_rects++].height = scan->next->y - scan->y; + } + } + + + } + paint = paint->next; + } + if (i_rects) + XFillRectangles(XtDisplay(ctx), XtWindow(ctx), gc, rects, i_rects); + + paint = list->paint; + i_rects = 0; + while (paint) { + if (paint->highlight) { + if (i_rects == 0) + XSetForeground(XtDisplay(ctx), gc, sink->text_sink.cursor_color); + if (i_rects <= n_rects) + rects = (XRectangle*) + XtRealloc((XtPointer)rects, sizeof(XRectangle) * + ++n_rects); + rects[i_rects].x = paint->x; + rects[i_rects].y = paint->y - paint->max_ascent; + rects[i_rects].width = paint->width; + rects[i_rects++].height = paint->max_ascent + paint->max_descent + 1; + } + paint = paint->next; + } + if (list->hightabs) { + for (scan = list->hightabs->scanline; scan && scan->next; + scan = scan->next) + for (seg = scan->segment; seg; seg = seg->next) { + if (i_rects == 0) + XSetForeground(XtDisplay(ctx), gc, + sink->text_sink.cursor_color); + if (i_rects <= n_rects) + rects = (XRectangle*) + XtRealloc((XtPointer)rects, sizeof(XRectangle) * + ++n_rects); + rects[i_rects].x = seg->x1; + rects[i_rects].y = scan->y; + rects[i_rects].width = seg->x2 - seg->x1; + rects[i_rects++].height = scan->next->y - scan->y; + } + } + + if (i_rects) + XFillRectangles(XtDisplay(ctx), XtWindow(ctx), gc, rects, i_rects); + if (rects) + XtFree((XtPointer)rects); + + /* pass 5: draw text! */ + paint = list->paint; + if (paint && (property = paint->property) == NULL) { + font = sink->ascii_sink.font; + XSetFont(XtDisplay(ctx), gc, font->fid); + if (!paint->highlight) + XSetForeground(XtDisplay(ctx), gc, sink->text_sink.foreground); + } + else + property = NULL; + highlight = False; + while (paint) { + if (!highlight && paint->highlight) + XSetForeground(XtDisplay(ctx), gc, sink->text_sink.background); + if (highlight || paint->highlight || paint->property != property) { + if (!paint->property || !(paint->property->mask & XAW_TPROP_FONT)) + font = sink->ascii_sink.font; + else + font = paint->property->font; + XSetFont(XtDisplay(ctx), gc, font->fid); + if (!paint->highlight) { + if (!paint->property || + !(paint->property->mask & XAW_TPROP_FOREGROUND)) + XSetForeground(XtDisplay(ctx), gc, + sink->text_sink.foreground); + else + XSetForeground(XtDisplay(ctx), gc, + paint->property->foreground); + } + highlight = paint->highlight; + property = paint->property; + } + + if (paint->x < XtWidth(ctx) && paint->x + paint->width > 0) { + XDrawString(XtDisplay(ctx), XtWindow(ctx), gc, paint->x, paint->y, + paint->text, paint->length); + if (property) { + if (property->mask & XAW_TPROP_UNDERLINE) { + if (line_width != property->underline_thickness) { + values.line_width = line_width = + property->underline_thickness; + XChangeGC(XtDisplay(ctx), gc, GCLineWidth, &values); + } + + XDrawLine(XtDisplay(ctx), XtWindow(ctx), gc, paint->x, + paint->y + property->underline_position, + paint->x + paint->width, + paint->y + property->underline_position); + } + if (property->mask & XAW_TPROP_OVERSTRIKE) { + if (line_width != property->underline_thickness) { + values.line_width = line_width = + property->underline_thickness; + XChangeGC(XtDisplay(ctx), gc, GCLineWidth, &values); + } + + XDrawLine(XtDisplay(ctx), XtWindow(ctx), gc, paint->x, + paint->y - (font->ascent>>1) + (font->descent>>1), + paint->x + paint->width, + paint->y - (font->ascent>>1) + (font->descent>>1)); + } + } + } + + paint = paint->next; + } + + /* pass 6: bearing clipping */ + /* dont care on order of drawing or caching of state (by now) */ + paint = list->bearings; + while (paint) { + XRectangle rect; + + if (paint->highlight) + XSetForeground(XtDisplay(ctx), gc, sink->text_sink.background); + if (!paint->property || !(paint->property->mask & XAW_TPROP_FONT)) + font = sink->ascii_sink.font; + else + font = paint->property->font; + XSetFont(XtDisplay(ctx), gc, font->fid); + if (!paint->highlight) { + if (!paint->property || + !(paint->property->mask & XAW_TPROP_FOREGROUND)) + XSetForeground(XtDisplay(ctx), gc, sink->text_sink.foreground); + else + XSetForeground(XtDisplay(ctx), gc, paint->property->foreground); + } + if (paint->x < XtWidth(ctx) && paint->x + paint->width > 0) { + rect.x = paint->x + paint->width; + rect.width = XawAbs(paint->width); /* more than enough */ + rect.y = paint->y - font->ascent; + rect.height = rect.y + font->ascent + font->descent; + XSetClipRectangles(XtDisplay((Widget)ctx), gc, + 0, 0, &rect, 1, Unsorted); + XDrawString(XtDisplay(ctx), XtWindow(ctx), gc, paint->x, paint->y, + paint->text, paint->length); + } + paint = paint->next; + } +} +#endif + +/* + * Function: + * PaintText + * + * Parameters: + * w - text sink object + * gc - gc to paint text with + * x - location to paint the text + * y - "" + * buf - buffer and length of text to paint. + * len - "" + * clear_bg - clear background before drawing ? + * + * Description: + * Actually paints the text into the window. + * + * Returns: + * the width of the text painted + */ +static unsigned int +PaintText(Widget w, GC gc, int x, int y, char *buf, int len, Bool clear_bg) +{ + AsciiSinkObject sink = (AsciiSinkObject)w; + TextWidget ctx = (TextWidget)XtParent(w); + int width = XTextWidth(sink->ascii_sink.font, buf, len); + + if ((x > XtWidth(ctx)) || width <= -x) /* Don't draw if we can't see it */ + return (width); + + if (clear_bg) { + _XawTextSinkClearToBackground(w, x, y - sink->ascii_sink.font->ascent, + width, sink->ascii_sink.font->ascent + + sink->ascii_sink.font->descent); + XDrawString(XtDisplay(ctx), XtWindow(ctx), gc, x, y, buf, len); + } + else + XDrawImageString(XtDisplay(ctx), XtWindow(ctx), gc, x, y, buf, len); + + return (width); +} + +static void +DisplayText(Widget w, int x, int y, + XawTextPosition pos1, XawTextPosition pos2, Bool highlight) +{ + TextWidget ctx = (TextWidget)XtParent(w); + AsciiSinkObject sink = (AsciiSinkObject)w; + XFontStruct *font = sink->ascii_sink.font; + Widget source = XawTextGetSource(XtParent(w)); + unsigned char buf[260]; + int j, k; + XawTextBlock blk; + GC gc, invgc, tabgc; + int max_x; + Bool clear_bg; + + if (!sink->ascii_sink.echo || !ctx->text.lt.lines) + return; + + max_x = (int)XtWidth(ctx) - ctx->text.r_margin.right; + clear_bg = !highlight && ctx->core.background_pixmap != XtUnspecifiedPixmap; + + gc = highlight ? sink->ascii_sink.invgc : sink->ascii_sink.normgc; + invgc = highlight ? sink->ascii_sink.normgc : sink->ascii_sink.invgc; + + if (highlight && sink->ascii_sink.xorgc) + tabgc = sink->ascii_sink.xorgc; + else + tabgc = invgc; + + y += sink->ascii_sink.font->ascent; + for (j = 0; pos1 < pos2;) { + pos1 = XawTextSourceRead(source, pos1, &blk, pos2 - pos1); + for (k = 0; k < blk.length; k++) { + if (j >= sizeof(buf) - 4) { /* buffer full, dump the text */ + if ((x += PaintText(w, gc, x, y, (char*)buf, j, clear_bg)) + >= max_x) + return; + j = 0; + } + buf[j] = blk.ptr[k]; + if (buf[j] == XawLF) /* line feeds ('\n') are not printed */ + continue; + + else if (buf[j] == '\t') { + int width; + + if (j != 0 + && (x += PaintText(w, gc, x, y, (char*)buf, j, clear_bg)) + >= max_x) + return; + + if ((width = CharWidth(sink, font, x, '\t')) > -x) { + if (clear_bg) + _XawTextSinkClearToBackground(w, x, y-font->ascent, width, + font->ascent+font->descent); + else + XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), + tabgc, x, y - font->ascent, width, + font->ascent + font->descent); + } + + if ((x += width) >= max_x) + return; + + j = -1; + } + else if ((buf[j] & 0177) < XawSP || buf[j] == 0177) { + if (sink->ascii_sink.display_nonprinting) { + unsigned char c = buf[j]; + + if (c > 0177) { + buf[j++] = '\\'; + buf[j++] = ((c >> 6) & 7) + '0'; + buf[j++] = ((c >> 3) & 7) + '0'; + buf[j] = (c & 7) + '0'; + } + else { + c |= 0100; + buf[j++] = '^'; + buf[j] = c == 0177 ? '?' : c; + } + } + else + buf[j] = ' '; + } + j++; + } + } + + if (j > 0) + (void)PaintText(w, gc, x, y, (char*)buf, j, clear_bg); +} + +/* + * Function: + * GetCursorBounds + * + * Parameters: + * w - text sink object + * rect - X rectangle to return the cursor bounds + * + * Description: + * Returns the size and location of the cursor. + */ +static void +GetCursorBounds(Widget w, XRectangle *rect) +{ + AsciiSinkObject sink = (AsciiSinkObject)w; + XFontStruct *font = sink->ascii_sink.font; + unsigned char ch; +#ifndef OLDXAW + TextWidget ctx = (TextWidget)XtParent(w); + XawTextBlock block; + XawTextAnchor *anchor; + XawTextEntity *entity; + XawTextProperty *property; + + if (XawTextSourceAnchorAndEntity(XawTextGetSource(XtParent(w)), + sink->ascii_sink.cursor_position, + &anchor, &entity)) { + if ((property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + font = property->font; + } + (void)XawTextSourceRead(XawTextGetSource((Widget)ctx), + ctx->text.insertPos, &block, 1); + if (!block.length || block.ptr[0] == '\n' || block.ptr[0] == '\t') + ch = ' '; + else if ((*((unsigned char*)block.ptr) & 0177) < XawSP || + *(unsigned char*)block.ptr == 0177) { + if (sink->ascii_sink.display_nonprinting) + ch = *((unsigned char*)block.ptr) > 0177 ? '\\' : '^'; + else + ch = ' '; + } + else + ch = *(unsigned char*)block.ptr; +#else + ch = ' '; +#endif + + rect->width = CharWidth(sink, font, 0, ch); + rect->height = font->descent + font->ascent + 1; + + rect->x = sink->ascii_sink.cursor_x; + rect->y = sink->ascii_sink.cursor_y - font->ascent; +} + +/* this function is required to support diferent fonts and correctly place + * the cursor. There are better ways to calculate the base line, but there is + * no place/code (yet) to store this information. + */ +static int +FindCursorY(TextWidget ctx, XawTextPosition position) +{ + int y, line, ascent; + AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink; +#ifndef OLDXAW + XawTextAnchor *anchor; + XawTextEntity *entity; + XawTextProperty *property; + XawTextPosition left, right; +#endif + + for (line = 0; line < ctx->text.lt.lines; line++) + if (position < ctx->text.lt.info[line + 1].position) + break; + + y = ctx->text.lt.info[line].y; +#ifndef OLDXAW + ascent = 0; + left = ctx->text.lt.info[line].position; + right = ctx->text.lt.info[line + 1].position; + right = XawMin(right, ctx->text.lastPos + 1); + while (left < right) { + if (XawTextSourceAnchorAndEntity(ctx->text.source, left, + &anchor, &entity)) { + if ((property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + ascent = XawMax(property->font->ascent, ascent); + else + ascent = XawMax(sink->ascii_sink.font->ascent, ascent); + left = anchor->position + entity->offset + entity->length; + } + else if (anchor) { + ascent = XawMax(sink->ascii_sink.font->ascent, ascent); + while (entity) { + XawTextPosition tmp = anchor->position + entity->offset + entity->length; + + if (tmp > left && tmp < right) { + left = tmp; + if ((property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + ascent = XawMax(property->font->ascent, ascent); + else + ascent = XawMax(sink->ascii_sink.font->ascent, ascent); + } + entity = entity->next; + } + if (entity == NULL) + break; + } + else { + ascent = XawMax(sink->ascii_sink.font->ascent, ascent); + break; + } + } + if (!ascent) + ascent = sink->ascii_sink.font->ascent; +#else + ascent = sink->ascii_sink.font->ascent; +#endif + + return (y + ascent); +} + +static void +InsertCursor(Widget w, int x, int y, XawTextInsertState state) +{ + AsciiSinkObject sink = (AsciiSinkObject)w; + XFontStruct *font = sink->ascii_sink.font; + TextWidget ctx = (TextWidget)XtParent(w); + XawTextPosition position = XawTextGetInsertionPoint((Widget)ctx); + Boolean overflow = (x & 0xffff8000) != 0; +#ifndef OLDXAW + XawTextAnchor *anchor; + XawTextEntity *entity; + XawTextProperty *property; +#endif + + if (XtIsRealized((Widget)ctx)) { + int fheight; + XawTextBlock block; + XawTextPosition selection_start, selection_end; + Boolean has_selection; + + if (!sink->ascii_sink.echo) { + if (sink->ascii_sink.laststate != state) { + int width = CharWidth(sink, font, 0, ' ') - 1; + + x = ctx->text.margin.left; + y = ctx->text.margin.top; + font = sink->ascii_sink.font; + fheight = font->ascent + font->descent; + if (state == XawisOn) { + if (ctx->text.hasfocus) + XFillRectangle(XtDisplay(ctx), XtWindow(ctx), + sink->ascii_sink.xorgc, x, y, + width + 1, fheight + 1); + else + XDrawRectangle(XtDisplay(ctx), XtWindow(ctx), + sink->ascii_sink.xorgc, x, y, + width, fheight); + + } + else + _XawTextSinkClearToBackground(w, x, y, + width + 1, fheight + 1); + } + sink->ascii_sink.cursor_x = x; + sink->ascii_sink.cursor_y = y; + sink->ascii_sink.laststate = state; + return; + } + + + XawTextGetSelectionPos((Widget)ctx, &selection_start, &selection_end); + has_selection = selection_start != selection_end; + + if (sink->ascii_sink.laststate != state) { + unsigned char ch; + +#ifndef OLDXAW + if (XawTextSourceAnchorAndEntity(ctx->text.source, + position, &anchor, &entity) && + (property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + font = property->font; + else + font = sink->ascii_sink.font; +#endif + + fheight = font->ascent + font->descent; + (void)XawTextSourceRead(XawTextGetSource((Widget)ctx), + position, &block, 1); + if (!block.length || block.ptr[0] == '\n' || block.ptr[0] == '\t') + ch = ' '; + else if ((*((unsigned char*)block.ptr) & 0177) < XawSP + || *(unsigned char*)block.ptr == 0177) { + if (sink->ascii_sink.display_nonprinting) + ch = *((unsigned char*)block.ptr) > 0177 ? '\\' : '^'; + else + ch = ' '; + } + else + ch = *(unsigned char*)block.ptr; + + y = FindCursorY(ctx, position); + if (ctx->text.hasfocus && !has_selection) + XFillRectangle(XtDisplay(ctx), XtWindow(ctx), + sink->ascii_sink.xorgc, x, y - font->ascent, + CharWidth(sink, font, 0, ch), fheight + 1); + else + XDrawRectangle(XtDisplay(ctx), XtWindow(ctx), + sink->ascii_sink.xorgc, x, y - font->ascent, + CharWidth(sink, font, 0, ch) - 1, fheight); + } + } + + sink->ascii_sink.cursor_x = overflow ? -16384 : x; + sink->ascii_sink.cursor_y = y; + sink->ascii_sink.laststate = state; + sink->ascii_sink.cursor_position = position; +} + +/* + * Given two positions, find the distance between them + */ +static void +FindDistance(Widget w, XawTextPosition fromPos, int fromx, + XawTextPosition toPos, int *resWidth, + XawTextPosition *resPos, int *resHeight) +{ +#ifndef OLDXAW + AsciiSinkObject sink = (AsciiSinkObject)w; + TextWidget ctx = (TextWidget)XtParent(w); + XFontStruct *font = sink->ascii_sink.font; + Widget source = ctx->text.source; + XawTextPosition idx, pos; + unsigned char c; + XawTextBlock blk; + int i, rWidth, ascent = 0, descent = 0; + XawTextAnchor *anchor; + XawTextEntity *entity; + XawTextProperty *property; + Cardinal length; + Bool done = False; + + pos = idx = fromPos; + rWidth = 0; + c = 0; + + while (!done) { + if (XawTextSourceAnchorAndEntity(source, pos, &anchor, &entity)) { + length = anchor->position + entity->offset + entity->length; + length = XawMin(toPos, length) - pos; + if ((property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + font = property->font; + else + font = sink->ascii_sink.font; + } + else { + if (anchor) { + while (entity && anchor->position + entity->offset < pos) + entity = entity->next; + if (entity) { + length = anchor->position + entity->offset; + length = XawMin(toPos, length) - pos; + } + else + length = XawMin(toPos - pos, 4096); + } + else + length = XawMin(toPos - pos, 4096); + font = sink->ascii_sink.font; + } + + ascent = XawMax(font->ascent, ascent); + descent = XawMax(font->descent, descent); + + pos = XawTextSourceRead(source, pos, &blk, length); + if (blk.length == 0 && pos == idx) /* eof reached */ + break; + + idx = blk.firstPos; + for (i = 0; idx < toPos; i++, idx++) { + if (i >= blk.length) + break; + c = blk.ptr[i]; + rWidth += CharWidth(sink, font, fromx + rWidth, c); + if (c == XawLF) { + idx++; + done = True; + break; + } + } + if (idx >= toPos) + break; + } + + *resPos = idx; + *resWidth = rWidth; + *resHeight = ascent + descent + 1; +#else + AsciiSinkObject sink = (AsciiSinkObject)w; + TextWidget ctx = (TextWidget)XtParent(w); + XFontStruct *font = sink->ascii_sink.font; + Widget source = ctx->text.source; + XawTextPosition idx, pos; + unsigned char c; + XawTextBlock blk; + int i, rWidth; + + pos = XawTextSourceRead(source, fromPos, &blk, toPos - fromPos); + rWidth = 0; + for (i = 0, idx = fromPos; idx < toPos; i++, idx++) { + if (i >= blk.length) { + i = 0; + pos = XawTextSourceRead(source, pos, &blk, toPos - pos); + if (blk.length == 0) + break; + } + c = blk.ptr[i]; + rWidth += CharWidth(sink, font, fromx + rWidth, c); + if (c == XawLF) { + idx++; + break; + } + } + + *resPos = idx; + *resWidth = rWidth; + *resHeight = font->ascent + font->descent + 1; +#endif +} + +static void +FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width, + Bool stopAtWordBreak, XawTextPosition *resPos, + int *resWidth, int *resHeight) +{ +#ifndef OLDXAW + AsciiSinkObject sink = (AsciiSinkObject)w; + TextWidget ctx = (TextWidget)XtParent(w); + Widget source = ctx->text.source; + XFontStruct *font = sink->ascii_sink.font; + XawTextPosition idx, pos, whiteSpacePosition = 0; + int i, lastWidth, whiteSpaceWidth, rWidth, ascent = 0, descent = 0; + Boolean whiteSpaceSeen; + unsigned char c; + XawTextBlock blk; + XawTextAnchor *anchor; + XawTextEntity *entity; + XawTextProperty *property; + Cardinal length; + Bool done = False; + + pos = idx = fromPos; + rWidth = lastWidth = whiteSpaceWidth = 0; + whiteSpaceSeen = False; + c = 0; + + while (!done) { + font = sink->ascii_sink.font; + if (XawTextSourceAnchorAndEntity(source, pos, &anchor, &entity)) { + length = anchor->position + entity->offset + entity->length - pos; + if ((property = XawTextSinkGetProperty((Widget)sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + font = property->font; + } + else { + if (anchor) { + while (entity && anchor->position + entity->offset < pos) + entity = entity->next; + if (entity) + length = anchor->position + entity->offset - pos; + else + length = 4096; + } + else + length = 4096; + } + + ascent = XawMax(font->ascent, ascent); + descent = XawMax(font->descent, descent); + + pos = XawTextSourceRead(source, pos, &blk, length); + if (blk.length == 0 && pos == idx) /* eof reached */ + break; + + idx = blk.firstPos; + for (i = 0; rWidth <= width && i < blk.length; i++, idx++) { + c = blk.ptr[i]; + lastWidth = rWidth; + rWidth += CharWidth(sink, font, fromx + rWidth, c); + + if (c == XawLF) { + idx++; + done = True; + break; + } + else if ((c == XawSP || c == XawTAB) && rWidth <= width) { + whiteSpaceSeen = True; + whiteSpacePosition = idx; + whiteSpaceWidth = rWidth; + } + } + if (rWidth > width) + break; + } + + if (rWidth > width && idx > fromPos) { + idx--; + rWidth = lastWidth; + if (stopAtWordBreak && whiteSpaceSeen) { + idx = whiteSpacePosition + 1; + rWidth = whiteSpaceWidth; + } + } + + if (idx >= ctx->text.lastPos && c != XawLF) + idx = ctx->text.lastPos + 1; + + *resPos = idx; + *resWidth = rWidth; + *resHeight = ascent + descent + 1; +#else + AsciiSinkObject sink = (AsciiSinkObject)w; + TextWidget ctx = (TextWidget)XtParent(w); + Widget source = ctx->text.source; + XFontStruct *font = sink->ascii_sink.font; + XawTextPosition idx, pos, whiteSpacePosition = 0; + int i, lastWidth, whiteSpaceWidth, rWidth; + Boolean whiteSpaceSeen; + unsigned char c; + XawTextBlock blk; + + pos = XawTextSourceRead(source, fromPos, &blk, BUFSIZ); + rWidth = lastWidth = whiteSpaceWidth = 0; + whiteSpaceSeen = False; + c = 0; + + for (i = 0, idx = fromPos; rWidth <= width; i++, idx++) { + if (i >= blk.length) { + i = 0; + pos = XawTextSourceRead(source, pos, &blk, BUFSIZ); + if (blk.length == 0) + break; + } + c = blk.ptr[i]; + lastWidth = rWidth; + rWidth += CharWidth(sink, font, fromx + rWidth, c); + + if (c == XawLF) { + idx++; + break; + } + else if ((c == XawSP || c == XawTAB) && rWidth <= width) { + whiteSpaceSeen = True; + whiteSpacePosition = idx; + whiteSpaceWidth = rWidth; + } + } + + if (rWidth > width && idx > fromPos) { + idx--; + rWidth = lastWidth; + if (stopAtWordBreak && whiteSpaceSeen) { + idx = whiteSpacePosition + 1; + rWidth = whiteSpaceWidth; + } + } + + if (idx >= ctx->text.lastPos && c != XawLF) + idx = ctx->text.lastPos + 1; + + *resPos = idx; + *resWidth = rWidth; + *resHeight = font->ascent + font->descent + 1; +#endif +} + +static void +Resolve(Widget w, XawTextPosition pos, int fromx, int width, + XawTextPosition *pos_return) +{ + int resWidth, resHeight; + Widget source = XawTextGetSource(XtParent(w)); + + FindPosition(w, pos, fromx, width, False, pos_return, &resWidth, &resHeight); + if (*pos_return > GETLASTPOS) + *pos_return = GETLASTPOS; +} + +static void +GetGC(AsciiSinkObject sink) +{ + XtGCMask valuemask = (GCFont | GCGraphicsExposures | GCClipXOrigin | + GCForeground | GCBackground); + XGCValues values; + + /* XXX We dont want do share a gc that will change the clip-mask */ + values.clip_x_origin = (long)sink; + values.clip_mask = None; + values.font = sink->ascii_sink.font->fid; + values.graphics_exposures = False; + + values.foreground = sink->text_sink.foreground; + values.background = sink->text_sink.background; + sink->ascii_sink.normgc = XtAllocateGC((Widget)sink, 0, valuemask, &values, + GCClipMask | GCFont | GCForeground | + GCBackground, 0); + + values.foreground = sink->text_sink.background; +#ifndef OLDXAW + values.background = sink->text_sink.cursor_color; +#else + values.background = sink->text_sink.foreground; +#endif + sink->ascii_sink.invgc = XtAllocateGC((Widget)sink, 0, valuemask, &values, + GCClipMask | GCFont, 0); + + valuemask |= GCFunction; + values.function = GXxor; +#ifndef OLDXAW + values.foreground = sink->text_sink.background ^ sink->text_sink.cursor_color; +#else + values.foreground = sink->text_sink.background ^ sink->text_sink.foreground; +#endif + values.background = 0L; + sink->ascii_sink.xorgc = XtAllocateGC((Widget)sink, 0, valuemask, + &values, GCClipMask | GCFont, 0); + + XawAsciiSinkResize((Widget)sink); +} + +/* Function: + * XawAsciiSinkInitialize + * + * Parameters: + * request - the requested and new values for the object instance + * cnew - "" + * + * Description: + * Initializes the TextSink Object. + */ +/*ARGSUSED*/ +static void +XawAsciiSinkInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + AsciiSinkObject sink = (AsciiSinkObject)cnew; + + GetGC(sink); + + if (!sink->ascii_sink.font) XtError("Aborting: no font found\n"); + + sink->ascii_sink.cursor_position = 0; + sink->ascii_sink.laststate = XawisOff; + sink->ascii_sink.cursor_x = sink->ascii_sink.cursor_y = 0; +} + +/* + * Function: + * XawAsciiSinkDestroy + * + * Parameters: + * w - AsciiSink Object + * + * Description: + * This function cleans up when the object is destroyed. + */ +static void +XawAsciiSinkDestroy(Widget w) +{ + AsciiSinkObject sink = (AsciiSinkObject)w; + + XtReleaseGC(w, sink->ascii_sink.normgc); + XtReleaseGC(w, sink->ascii_sink.invgc); + XtReleaseGC(w, sink->ascii_sink.xorgc); + + sink->ascii_sink.normgc = + sink->ascii_sink.invgc = + sink->ascii_sink.xorgc = NULL; +} + +static void +XawAsciiSinkResize(Widget w) +{ + TextWidget ctx = (TextWidget)XtParent(w); + AsciiSinkObject sink = (AsciiSinkObject)w; + XRectangle rect; + int width, height; + + if (w->core.widget_class != asciiSinkObjectClass) + return; + + rect.x = ctx->text.r_margin.left; + rect.y = ctx->text.r_margin.top; + width = (int)XtWidth(ctx) - RHMargins(ctx); + height = (int)XtHeight(ctx) - RVMargins(ctx); + rect.width = width; + rect.height = height; + + if (sink->ascii_sink.normgc) { + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), sink->ascii_sink.normgc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), sink->ascii_sink.normgc, None); + } + if (sink->ascii_sink.invgc) { + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), sink->ascii_sink.invgc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), sink->ascii_sink.invgc, None); + } + if (sink->ascii_sink.xorgc) { + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), sink->ascii_sink.xorgc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), sink->ascii_sink.xorgc, None); + } +} + +/* + * Function: + * XawAsciiSinkSetValues + * + * Parameters: + * current - current state of the object + * request - what was requested + * cnew - what the object will become + * + * Description: + * Sets the values for the AsciiSink. + * + * Returns: + * True if redisplay is needed + */ +/*ARGSUSED*/ +static Boolean +XawAsciiSinkSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + AsciiSinkObject w = (AsciiSinkObject)cnew; + AsciiSinkObject old_w = (AsciiSinkObject)current; + + if (w->ascii_sink.font != old_w->ascii_sink.font + || w->text_sink.background != old_w->text_sink.background + || w->text_sink.foreground != old_w->text_sink.foreground +#ifndef OLDXAW + || w->text_sink.cursor_color != old_w->text_sink.cursor_color + || w->text_sink.properties != old_w->text_sink.properties +#endif + ) { +#ifdef OLDXAW + XtReleaseGC(cnew, w->ascii_sink.normgc); + XtReleaseGC(cnew, w->ascii_sink.invgc); + XtReleaseGC(cnew, w->ascii_sink.xorgc); + GetGC(w); +#endif + ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; + } + else if (w->ascii_sink.echo != old_w->ascii_sink.echo + || w->ascii_sink.display_nonprinting + != old_w->ascii_sink.display_nonprinting) + ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; +#ifndef OLDXAW + if (w->text_sink.properties != old_w->text_sink.properties) { + XawTextProperty *property = + XawTextSinkGetProperty(cnew, XrmStringToQuark("default")); + + if (property) { + if (property->mask & XAW_TPROP_FONT) + w->ascii_sink.font = property->font; + if (property->mask & XAW_TPROP_FOREGROUND) + w->text_sink.foreground = property->foreground; + if (property->mask & XAW_TPROP_BACKGROUND) + w->text_sink.background = property->background; + } + } +#endif + + return (False); +} + +/* + * Function: + * MaxLines + * + * Parameters: + * w - AsciiSink Object + * height - height to fit lines into + * + * Description: + * Finds the Maximum number of lines that will fit in a given height. + * + * Returns: + * The number of lines that will fit + */ +/*ARGSUSED*/ +static int +MaxLines(Widget w, unsigned int height) +{ + AsciiSinkObject sink = (AsciiSinkObject)w; + int font_height; + + font_height = sink->ascii_sink.font->ascent + sink->ascii_sink.font->descent + 1; + + return ((int)height / font_height); +} + +/* + * Function: + * MaxHeight + * + * Parameters: + * w - AsciiSink Object + * lines - number of lines + * + * Description: + * Finds the Minium height that will contain a given number lines. + * + * Returns: + * the height + */ +static int +MaxHeight(Widget w, int lines) +{ + AsciiSinkObject sink = (AsciiSinkObject)w; + + return (lines * (sink->ascii_sink.font->ascent + + sink->ascii_sink.font->descent + 1)); +} + +/* + * Function: + * SetTabs + * + * Parameters: + * w - AsciiSink Object + * tab_count - number of tabs in the list + * tabs - text positions of the tabs + * + * Description: + * Sets the Tab stops. + */ +static void +SetTabs(Widget w, int tab_count, short *tabs) +{ + AsciiSinkObject sink = (AsciiSinkObject)w; + int i; + Atom XA_FIGURE_WIDTH; + unsigned long figure_width = 0; + XFontStruct *font = sink->ascii_sink.font; + + /* + * Find the figure width of the current font + */ + XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", False); + if (XA_FIGURE_WIDTH != None + && (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width) + || figure_width == 0)) { + if (font->per_char && font->min_char_or_byte2 <= '$' + && font->max_char_or_byte2 >= '$') + figure_width = font->per_char['$' - font->min_char_or_byte2].width; + else + figure_width = font->max_bounds.width; + } + + if (tab_count > sink->text_sink.tab_count) { + sink->text_sink.tabs = (Position *) + XtRealloc((char*)sink->text_sink.tabs, tab_count * sizeof(Position)); + sink->text_sink.char_tabs = (short *) + XtRealloc((char*)sink->text_sink.char_tabs, tab_count * sizeof(short)); + } + + for (i = 0 ; i < tab_count ; i++) { + sink->text_sink.tabs[i] = tabs[i] * figure_width; + sink->text_sink.char_tabs[i] = tabs[i]; + } + + sink->text_sink.tab_count = tab_count; + +#ifndef NO_TAB_FIX + { + TextWidget ctx = (TextWidget)XtParent(w); + ctx->text.redisplay_needed = True; + _XawTextBuildLineTable(ctx, ctx->text.lt.top, True); + } +#endif +} diff --git a/src/AsciiSrc.c b/src/AsciiSrc.c new file mode 100644 index 0000000..b28b2c4 --- /dev/null +++ b/src/AsciiSrc.c @@ -0,0 +1,1888 @@ +/* + +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* + * AsciiSrc.c - AsciiSrc object. (For use with the text widget). + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef OLDXAW +#include +#include +#endif +#include "Private.h" + +#include +#include +#include + +#if (defined(ASCII_STRING) || defined(ASCII_DISK)) +#include /* for Widget Classes */ +#endif + +#ifdef X_NOT_POSIX +#define Off_t long +#define Size_t unsigned int +#else +#define Off_t off_t +#define Size_t size_t +#endif + +#define MAGIC_VALUE ((XawTextPosition)-1) +#define streq(a, b) (strcmp((a), (b)) == 0) + +/* + * Class Methods + */ +static void XawAsciiSrcClassInitialize(void); +static void XawAsciiSrcDestroy(Widget); +static void XawAsciiSrcGetValuesHook(Widget, ArgList, Cardinal*); +static void XawAsciiSrcInitialize(Widget, Widget, ArgList, Cardinal*); +static Boolean XawAsciiSrcSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static XawTextPosition ReadText(Widget, XawTextPosition, XawTextBlock*, int); +static int ReplaceText(Widget, XawTextPosition, XawTextPosition, + XawTextBlock*); +static XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType, + XawTextScanDirection, int, Bool); +static XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection, + XawTextBlock*); + +/* + * Prototypes + */ +static Piece *AllocNewPiece(AsciiSrcObject, Piece*); +static void BreakPiece(AsciiSrcObject, Piece*); +static Boolean CvtAsciiTypeToString(Display*, XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr, XtPointer*); +static void CvtStringToAsciiType(XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr); +static Piece *FindPiece(AsciiSrcObject, XawTextPosition, XawTextPosition*); +static void FreeAllPieces(AsciiSrcObject); +static FILE *InitStringOrFile(AsciiSrcObject, Bool); +static void LoadPieces(AsciiSrcObject, FILE*, char*); +static void RemoveOldStringOrFile(AsciiSrcObject, Bool); +static void RemovePiece(AsciiSrcObject, Piece*); +static String StorePiecesInString(AsciiSrcObject); +static Bool WriteToFile(String, String, unsigned); +static Bool WritePiecesToFile(AsciiSrcObject, String); +static void GetDefaultPieceSize(Widget, int, XrmValue*); + +/* + * More Prototypes + */ +#ifdef ASCII_DISK +Widget XawAsciiDiskSourceCreate(Widget, ArgList, Cardinal); +#endif +#ifdef ASCII_STRING +Widget XawStringSourceCreate(Widget, ArgList, Cardinal); +void XawTextSetLastPos(Widget, XawTextPosition); +#endif + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(AsciiSrcRec, ascii_src.field) +static XtResource resources[] = { + { + XtNstring, + XtCString, + XtRString, + sizeof(char*), + offset(string), + XtRString, + NULL + }, + { + XtNtype, + XtCType, + XtRAsciiType, + sizeof(XawAsciiType), + offset(type), + XtRImmediate, + (XtPointer)XawAsciiString + }, + { + XtNdataCompression, + XtCDataCompression, + XtRBoolean, + sizeof(Boolean), + offset(data_compression), + XtRImmediate, + (XtPointer)True + }, + { + XtNpieceSize, + XtCPieceSize, + XtRInt, + sizeof(XawTextPosition), + offset(piece_size), + XtRCallProc, + (XtPointer)GetDefaultPieceSize + }, +#ifdef OLDXAW + { + XtNcallback, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + offset(callback), + XtRCallback, + (XtPointer)NULL + }, +#endif + { + XtNuseStringInPlace, + XtCUseStringInPlace, + XtRBoolean, + sizeof(Boolean), + offset(use_string_in_place), + XtRImmediate, + (XtPointer)False + }, + { + XtNlength, + XtCLength, + XtRInt, + sizeof(int), + offset(ascii_length), + XtRImmediate, + (XtPointer)MAGIC_VALUE + }, +#ifdef ASCII_DISK + { + XtNfile, + XtCFile, + XtRString, + sizeof(String), + offset(filename), + XtRString, + NULL + }, +#endif /* ASCII_DISK */ +}; +#undef offset + + +#define Superclass (&textSrcClassRec) +AsciiSrcClassRec asciiSrcClassRec = { + /* object */ + { + (WidgetClass)Superclass, /* superclass */ + "AsciiSrc", /* class_name */ + sizeof(AsciiSrcRec), /* widget_size */ + XawAsciiSrcClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawAsciiSrcInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* compress_motion */ + False, /* compress_exposure */ + False, /* compress_enterleave */ + False, /* visible_interest */ + XawAsciiSrcDestroy, /* destroy */ + NULL, /* resize */ + NULL, /* expose */ + XawAsciiSrcSetValues, /* set_values */ + NULL, /* set_values_hook */ + NULL, /* set_values_almost */ + XawAsciiSrcGetValuesHook, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + NULL, /* query_geometry */ + NULL, /* display_accelerator */ + NULL, /* extension */ + }, + /* text_src */ + { + ReadText, /* Read */ + ReplaceText, /* Replace */ + Scan, /* Scan */ + Search, /* Search */ + XtInheritSetSelection, /* SetSelection */ + XtInheritConvertSelection, /* ConvertSelection */ + }, + /* ascii_src */ + { + NULL, /* extension */ + }, +}; + +WidgetClass asciiSrcObjectClass = (WidgetClass)&asciiSrcClassRec; + +static XrmQuark Qstring, Qfile; + +/* + * Implementation + */ +/* + * Function: + * XawAsciiSrcClassInitialize() + * + * Description: + * Initializes the asciiSrcObjectClass and install the converters for + * AsciiType <-> String. + */ +static void +XawAsciiSrcClassInitialize(void) +{ + XawInitializeWidgetSet(); + Qstring = XrmPermStringToQuark(XtEstring); + Qfile = XrmPermStringToQuark(XtEfile); + XtAddConverter(XtRString, XtRAsciiType, CvtStringToAsciiType, NULL, 0); + XtSetTypeConverter(XtRAsciiType, XtRString, CvtAsciiTypeToString, + NULL, 0, XtCacheNone, NULL); +} + +/* + * Function: + * XawAsciiSrcInitialize + * + * Parameters: + * request - widget requested by the argument list + * cnew - new widget with both resource and non resource values + * args - (unused) + * num_args - (unused) + * + * Description: + * Initializes the ascii src object. + */ +/*ARGSUSED*/ +static void +XawAsciiSrcInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + AsciiSrcObject src = (AsciiSrcObject)cnew; + FILE *file; + + /* + * Set correct flags (override resources) depending upon widget class + */ + src->text_src.text_format = XawFmt8Bit; + +#ifdef ASCII_DISK + if (XtIsSubclass(XtParent(cnew), asciiDiskWidgetClass)) { + src->ascii_src.type = XawAsciiFile; + src->ascii_src.string = src->ascii_src.filename; + } +#endif + +#ifdef ASCII_STRING + if (XtIsSubclass(XtParent(cnew), asciiStringWidgetClass)) { + src->ascii_src.use_string_in_place = True; + src->ascii_src.type = XawAsciiString; + } +#endif + +#ifdef OLDXAW + src->ascii_src.changes = False; +#else + src->text_src.changed = False; +#endif + src->ascii_src.allocated_string = False; + + if (src->ascii_src.use_string_in_place && src->ascii_src.string == NULL) + src->ascii_src.use_string_in_place = False; + + file = InitStringOrFile(src, src->ascii_src.type == XawAsciiFile); + LoadPieces(src, file, NULL); + + if (file != NULL) + fclose(file); +} + +/* + * Function: + * ReadText + * + * Parameters: + * w - AsciiSource widget + * pos - position of the text to retreive. + * text - text block that will contain returned text + * length - maximum number of characters to read + * + * Description: + * This function reads the source. + * + * Returns: + * The character position following the retrieved text. + */ +static XawTextPosition +ReadText(Widget w, XawTextPosition pos, XawTextBlock *text, int length) +{ + AsciiSrcObject src = (AsciiSrcObject)w; + XawTextPosition count, start; + Piece *piece; +#ifndef OLDXAW + XawTextAnchor *anchor; + XawTextEntity *entity; + XawTextPosition offset, end = pos + length; + Bool state; + + end = XawMin(end, src->ascii_src.length); + while ((state = XawTextSourceAnchorAndEntity(w, pos, &anchor, &entity)) && + (entity->flags & XAW_TENTF_HIDE)) + pos = anchor->position + entity->offset + entity->length; + if (state == False || + !(entity->flags & XAW_TENTF_REPLACE)) { + while (entity) { + offset = anchor->position + entity->offset; + if (offset >= end) + break; + if (offset > pos && + (entity->flags & (XAW_TENTF_HIDE | XAW_TENTF_REPLACE))) { + end = XawMin(end, offset); + break; + } + if ((entity = entity->next) == NULL && + (anchor = XawTextSourceNextAnchor(w, anchor)) != NULL) + entity = anchor->entities; + } + } + else if (state && (entity->flags & XAW_TENTF_REPLACE) && pos < end) { + XawTextBlock *block = (XawTextBlock*)entity->data; + + offset = anchor->position + entity->offset; + end = XawMin(end, offset + block->length); + if ((length = end - pos) < 0) + length = 0; + text->length = length; + text->format = XawFmt8Bit; + if (length == 0) { + text->firstPos = end = offset + entity->length; + text->ptr = ""; + } + else { + text->firstPos = pos; + text->ptr = block->ptr + (pos - offset); + if (pos + length < offset + block->length) + end = pos + length; /* there is data left to be read */ + else + end = offset + entity->length; + } + + return (end); + } + + if ((length = end - pos) < 0) + length = 0; +#endif + + piece = FindPiece(src, pos, &start); + text->firstPos = pos; + text->ptr = piece->text + (pos - start); + count = piece->used - (pos - start); + text->length = Max(0, (length > count) ? count : length); + text->format = XawFmt8Bit; + + return (pos + text->length); +} + +/* + * Function: + * ReplaceText + * + * Parameters: + * w - AsciiSource object + * startPos - ends of text that will be replaced + * endPos - "" + * text - new text to be inserted into buffer at startPos + * + * Description: + * Replaces a block of text with new text. + * + * Returns: + * XawEditDone on success, XawEditError otherwise + */ +/*ARGSUSED*/ +static int +ReplaceText(Widget w, XawTextPosition startPos, XawTextPosition endPos, + XawTextBlock *text) +{ + AsciiSrcObject src = (AsciiSrcObject)w; + Piece *start_piece, *end_piece, *temp_piece; + XawTextPosition start_first, end_first; + int length, firstPos; + + /* + * Editing a read only source is not allowed + */ + if (src->text_src.edit_mode == XawtextRead) + return (XawEditError); + + start_piece = FindPiece(src, startPos, &start_first); + end_piece = FindPiece(src, endPos, &end_first); + +#ifndef OLDXAW + /* + * This is a big hack, but I can't think about a clever way to know + * if the character being moved forward has a negative lbearing. + * + */ + if (start_piece->used) { + int i; + + for (i = 0; i < src->text_src.num_text; i++) { + int line; + TextWidget ctx = (TextWidget)src->text_src.text[i]; + + for (line = 0; line < ctx->text.lt.lines; line++) + if (startPos < ctx->text.lt.info[line + 1].position) + break; + if (i < ctx->text.lt.lines && + startPos > ctx->text.lt.info[i].position) { + AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink; + XawTextAnchor *anchor; + XawTextEntity *entity; + XawTextProperty *property; + XFontStruct *font; + + if (XawTextSourceAnchorAndEntity(w, startPos, &anchor, &entity) && + (property = XawTextSinkGetProperty(ctx->text.sink, + entity->property)) != NULL && + (property->mask & XAW_TPROP_FONT)) + font = property->font; + else + font = sink->ascii_sink.font; + + if (font->min_bounds.lbearing < 0) { + int lbearing = font->min_bounds.lbearing; + unsigned char c = *(unsigned char*) + (start_piece->text + (startPos - start_first)); + + if (c == '\t' || c == '\n') + c = ' '; + else if ((c & 0177) < XawSP || c == 0177) { + if (sink->ascii_sink.display_nonprinting) + c = c > 0177 ? '\\' : c + '^'; + else + c = ' '; + } + if (font->per_char && + (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2)) + lbearing = font->per_char[c - font->min_char_or_byte2].lbearing; + if (lbearing < 0) + _XawTextNeedsUpdating(ctx, startPos - 1, startPos); + } + } + } + } + + +#endif + + /* + * Remove Old Stuff + */ + if (start_piece != end_piece) { + temp_piece = start_piece->next; + + /* + * If empty and not the only piece then remove it. + */ + if (((start_piece->used = startPos - start_first) == 0) + && !(start_piece->next == NULL && start_piece->prev == NULL)) + RemovePiece(src, start_piece); + + while (temp_piece != end_piece) { + temp_piece = temp_piece->next; + RemovePiece(src, temp_piece->prev); + } + + end_piece->used -= endPos - end_first; + if (end_piece->used != 0) + memmove(end_piece->text, end_piece->text + endPos - end_first, + (unsigned)end_piece->used); + } + else { /* We are fully in one piece */ + if ((start_piece->used -= endPos - startPos) == 0) { + if (!(start_piece->next == NULL && start_piece->prev == NULL)) + RemovePiece(src, start_piece); + } + else { + memmove(start_piece->text + (startPos - start_first), + start_piece->text + (endPos - start_first), + (unsigned)(start_piece->used - (startPos - start_first))); + if (src->ascii_src.use_string_in_place + && src->ascii_src.length - (endPos - startPos) + < src->ascii_src.piece_size - 1) + start_piece->text[src->ascii_src.length - (endPos - startPos)] = + '\0'; + } + } + + src->ascii_src.length += -(endPos - startPos) + text->length; + + if ( text->length != 0) { + /* + * Put in the New Stuff + */ + start_piece = FindPiece(src, startPos, &start_first); + + length = text->length; + firstPos = text->firstPos; + + while (length > 0) { + char *ptr; + int fill; + + if (src->ascii_src.use_string_in_place) { + if (start_piece->used == src->ascii_src.piece_size - 1) { + /* + * If we are in ascii string emulation mode. Then the + * string is not allowed to grow + */ + start_piece->used = src->ascii_src.length = + src->ascii_src.piece_size - 1; + start_piece->text[src->ascii_src.length] = '\0'; + return (XawEditError); + } + } + + if (start_piece->used == src->ascii_src.piece_size) { + BreakPiece(src, start_piece); + start_piece = FindPiece(src, startPos, &start_first); + } + + fill = Min((int)(src->ascii_src.piece_size - start_piece->used), + length); + + ptr = start_piece->text + (startPos - start_first); + memmove(ptr + fill, ptr, + (unsigned)(start_piece->used - (startPos - start_first))); + memcpy(ptr, text->ptr + firstPos, (unsigned)fill); + + startPos += fill; + firstPos += fill; + start_piece->used += fill; + length -= fill; + } + } + + if (src->ascii_src.use_string_in_place) + start_piece->text[start_piece->used] = '\0'; + +#ifdef OLDXAW + src->ascii_src.changes = True; + XtCallCallbacks(w, XtNcallback, NULL); +#endif + + return (XawEditDone); +} + +/* + * Function: + * Scan + * + * Parameters: + * w - AsciiSource object + * position - position to start scanning + * type - type of thing to scan for + * dir - direction to scan + * count - which occurance if this thing to search for. + * include - whether or not to include the character found in + * the position that is returned + * + * Description: + * Scans the text source for the number and type of item specified. + * + * Returns: + * The position of the item found + * + * Note: + * While there are only 'n' characters in the file there are n+1 + * possible cursor positions (one before the first character and + * one after the last character + */ +static XawTextPosition +Scan(Widget w, register XawTextPosition position, XawTextScanType type, + XawTextScanDirection dir, int count, Bool include) +{ + AsciiSrcObject src = (AsciiSrcObject)w; + Piece *piece; + XawTextPosition first, first_eol_position = 0; + register char *ptr, *lim; + register int cnt = count; + register unsigned char c; + + if (dir == XawsdLeft) { + if (position <= 0) + return (0); + --position; + } + else if (position >= src->ascii_src.length) + return (src->ascii_src.length); + + piece = FindPiece(src, position, &first); + if (piece->used == 0) + return (0); + + ptr = (position - first) + piece->text; + + if (dir == XawsdRight) { + lim = piece->text + piece->used; + switch (type) { + case XawstEOL: + case XawstParagraph: + case XawstWhiteSpace: + case XawstAlphaNumeric: + for (; cnt > 0; cnt--) { + Bool non_space = False, first_eol = True; + + /*CONSTCOND*/ + while (True) { + if (ptr >= lim) { + piece = piece->next; + if (piece == NULL) /* End of text */ + return (src->ascii_src.length); + ptr = piece->text; + lim = piece->text + piece->used; + } + + c = *ptr++; + ++position; + + if (type == XawstEOL) { + if (c == '\n') + break; + } + else if (type == XawstAlphaNumeric) { + if (!isalnum(c)) { + if (non_space) + break; + } + else + non_space = True; + } + else if (type == XawstWhiteSpace) { + if (isspace(c)) { + if (non_space) + break; + } + else + non_space = True; + } + else { /* XawstParagraph */ + if (first_eol) { + if (c == '\n') { + first_eol_position = position; + first_eol = False; + } + } + else if (c == '\n') + break; + else if (!isspace(c)) + first_eol = True; + } + } + } + break; + case XawstPositions: + position += count; + return (position < src->ascii_src.length ? + position : src->ascii_src.length); + case XawstAll: + return (src->ascii_src.length); + default: + break; + } + if (!include) { + if (type == XawstParagraph) + position = first_eol_position; + if (count) + --position; + } + } + else { + lim = piece->text; + switch (type) { + case XawstEOL: + case XawstParagraph: + case XawstWhiteSpace: + case XawstAlphaNumeric: + for (; cnt > 0; cnt--) { + Bool non_space = False, first_eol = True; + + /*CONSTCOND*/ + while (True) { + if (ptr < lim) { + piece = piece->prev; + if (piece == NULL) /* Begining of text */ + return (0); + ptr = piece->text + piece->used - 1; + lim = piece->text; + } + + c = *ptr--; + --position; + + if (type == XawstEOL) { + if (c == '\n') + break; + } + else if (type == XawstAlphaNumeric) { + if (!isalnum(c)) { + if (non_space) + break; + } + else + non_space = True; + } + else if (type == XawstWhiteSpace) { + if (isspace(c)) { + if (non_space) + break; + } + else + non_space = True; + } + else { /* XawstParagraph */ + if (first_eol) { + if (c == '\n') { + first_eol_position = position; + first_eol = False; + } + } + else if (c == '\n') + break; + else if (!isspace(c)) + first_eol = True; + } + } + } + break; + case XawstPositions: + position -= count - 1; + return (position > 0 ? position : 0); + case XawstAll: + return (0); + default: + break; + } + if (!include) { + if (type == XawstParagraph) + position = first_eol_position; + if (count) + ++position; + } + position++; + } + + return (position); +} + +/* + * Function: + * Search + * + * Parameters: + * w - AsciiSource object + * position - the position to start scanning + * dir - direction to scan + * text - text block to search for + * + * Description: + * Searchs the text source for the text block passed. + * + * Returns: + * The position of the item found + */ +static XawTextPosition +Search(Widget w, register XawTextPosition position, XawTextScanDirection dir, + XawTextBlock *text) +{ + AsciiSrcObject src = (AsciiSrcObject)w; + register int count = 0; + register char *ptr, c; + char *str; + Piece *piece; + char *buf; + XawTextPosition first; + int cnt, case_sensitive; + + if (dir == XawsdLeft) { + if (position == 0) + return (XawTextSearchError); + position--; + } + + buf = XtMalloc((unsigned)sizeof(unsigned char) * text->length); + memcpy(buf, text->ptr, (unsigned)text->length); + piece = FindPiece(src, position, &first); + ptr = (position - first) + piece->text; + case_sensitive = text->firstPos; + + if (dir == XawsdRight) { + str = buf; + c = *str; + /*CONSTCOND*/ + while (1) { + if (*ptr++ == c + || (case_sensitive && isalpha(c) && isalpha(ptr[-1]) + && toupper(c) == toupper(ptr[-1]))) { + if (++count == text->length) + break; + c = *++str; + } + else if (count) { + ptr -= count; + str -= count; + position -= count; + count = 0; + c = *str; + + if (ptr < piece->text) { + do { + cnt = piece->text - ptr; + piece = piece->prev; + if (piece == NULL) { + XtFree(buf); + return (XawTextSearchError); + } + ptr = piece->text + piece->used - cnt; + } while (ptr < piece->text); + } + } + position++; + if (ptr >= (piece->text + piece->used)) { + do { + cnt = ptr - (piece->text + piece->used); + piece = piece->next; + if (piece == NULL) { + XtFree(buf); + return (XawTextSearchError); + } + ptr = piece->text + cnt; + } while (ptr >= (piece->text + piece->used)); + } + } + + position -= text->length - 1; + } + else { + str = buf + text->length - 1; + c = *str; + /*CONSTCOND*/ + while (1) { + if (*ptr-- == c + || (case_sensitive && isalpha(c) && isalpha(ptr[1]) + && toupper(c) == toupper(ptr[1]))) { + if (++count == text->length) + break; + c = *--str; + } + else if (count) { + ptr += count; + str += count; + position += count; + count = 0; + c = *str; + + if (ptr >= (piece->text + piece->used)) { + do { + cnt = ptr - (piece->text + piece->used); + piece = piece->next; + if (piece == NULL) { + XtFree(buf); + return (XawTextSearchError); + } + ptr = piece->text + cnt; + } while (ptr >= (piece->text + piece->used)); + } + } + position--; + if (ptr < piece->text) { + do { + cnt = piece->text - ptr; + piece = piece->prev; + if (piece == NULL) { + XtFree(buf); + return (XawTextSearchError); + } + ptr = piece->text + piece->used - cnt; + } while (ptr < piece->text); + } + } + } + + XtFree(buf); + + return (position); +} + +/* + * Function: + * XawAsciiSrcSetValues + * + * Parameters: + * current - current state of the widget + * request - what was requested + * cnew - what the widget will become + * args - representation of changed resources + * num_args - number of resources that have changed + * + * Description: + * Sets the values for the AsciiSource. + * + * Returns: + * True if redisplay is needed + */ +static Boolean +XawAsciiSrcSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + AsciiSrcObject src = (AsciiSrcObject)cnew; + AsciiSrcObject old_src = (AsciiSrcObject)current; + Bool total_reset = False, string_set = False; + FILE *file; + unsigned int i; + + if (old_src->ascii_src.use_string_in_place + != src->ascii_src.use_string_in_place) { + XtAppWarning(XtWidgetToApplicationContext(cnew), + "AsciiSrc: The XtNuseStringInPlace resource may " + "not be changed."); + src->ascii_src.use_string_in_place = + old_src->ascii_src.use_string_in_place; + } + + for (i = 0; i < *num_args ; i++) + if (streq(args[i].name, XtNstring)) { + string_set = True; + break; + } + + if (string_set || (old_src->ascii_src.type != src->ascii_src.type)) { + RemoveOldStringOrFile(old_src, string_set); /* remove old info */ + file = InitStringOrFile(src, string_set); /* Init new info */ + LoadPieces(src, file, NULL); /* load new info into internal buffers */ + if (file != NULL) + fclose(file); +#ifndef OLDXAW + for (i = 0; i < src->text_src.num_text; i++) + /* Tell text widget what happened */ + XawTextSetSource(src->text_src.text[i], cnew, 0); +#else + XawTextSetSource(XtParent(cnew), cnew, 0); +#endif + total_reset = True; + } + + if (old_src->ascii_src.ascii_length != src->ascii_src.ascii_length) + src->ascii_src.piece_size = src->ascii_src.ascii_length + 1; + + if (!total_reset && + old_src->ascii_src.piece_size != src->ascii_src.piece_size) { + String string = StorePiecesInString(old_src); + + FreeAllPieces(old_src); + LoadPieces(src, NULL, string); + XtFree(string); + } + + return (False); +} + +/* + * Function: + * XawAsciiSrcGetValuesHook + * + * Parameters: + * w - AsciiSource Widget + * args - argument list + * num_args - number of args + * + * Description: + * This is a get values hook routine that sets the + * values specific to the ascii source. + */ +static void +XawAsciiSrcGetValuesHook(Widget w, ArgList args, Cardinal *num_args) +{ + AsciiSrcObject src = (AsciiSrcObject)w; + unsigned int i; + + if (src->ascii_src.type == XawAsciiString) { + for (i = 0; i < *num_args ; i++) + if (streq(args[i].name, XtNstring)) { + if (src->ascii_src.use_string_in_place) + *((char **)args[i].value) = src->ascii_src.first_piece->text; + else if (XawAsciiSave(w)) /* If save sucessful */ + *((char **)args[i].value) = src->ascii_src.string; + break; + } + } + } + +/* + * Function: + * XawAsciiSrcDestroy + * + * Parameters: + * src - Ascii source object to free + * + * Description: + * Destroys an ascii source (frees all data) + */ +static void +XawAsciiSrcDestroy(Widget w) +{ + RemoveOldStringOrFile((AsciiSrcObject) w, True); +} + +/* + * Public routines + */ +/* + * Function: + * XawAsciiSourceFreeString + * + * Parameters: + * w - AsciiSrc widget + * + * Description: + * Frees the string returned by a get values call + * on the string when the source is of type string. + */ +void +XawAsciiSourceFreeString(Widget w) +{ + AsciiSrcObject src = (AsciiSrcObject)w; + + /* If the src is really a multi, call the multi routine */ + if (XtIsSubclass(w, multiSrcObjectClass)) { + _XawMultiSourceFreeString(w); + return; + } + else if (!XtIsSubclass(w, asciiSrcObjectClass)) { + XtErrorMsg("bad argument", "asciiSource", "XawError", + "XawAsciiSourceFreeString's parameter must be " + "an asciiSrc or multiSrc.", + NULL, NULL); + } + + if (src->ascii_src.allocated_string && src->ascii_src.type != XawAsciiFile) { + src->ascii_src.allocated_string = False; + XtFree(src->ascii_src.string); + src->ascii_src.string = NULL; + } +} + +/* + * Function: + * XawAsciiSave + * + * Parameters: + * w - asciiSrc Widget + * + * Description: + * Saves all the pieces into a file or string as required. + * + * Returns: + * True if the save was successful + */ +Bool +XawAsciiSave(Widget w) +{ + AsciiSrcObject src = (AsciiSrcObject)w; + + /* If the src is really a multi, call the multi save */ + if (XtIsSubclass(w, multiSrcObjectClass )) + return (_XawMultiSave(w)); + + else if (!XtIsSubclass(w, asciiSrcObjectClass)) + XtErrorMsg("bad argument", "asciiSource", "XawError", + "XawAsciiSave's parameter must be an asciiSrc or multiSrc.", + NULL, NULL); + + /* + * If using the string in place then there is no need to play games + * to get the internal info into a readable string. + */ + if (src->ascii_src.use_string_in_place) + return (True); + + if (src->ascii_src.type == XawAsciiFile) { +#ifdef OLDXAW + if (!src->ascii_src.changes) +#else + if (!src->text_src.changed) /* No changes to save */ +#endif + return (True); + + if (WritePiecesToFile(src, src->ascii_src.string) == False) + return (False); + } + else { + if (src->ascii_src.allocated_string == True) + XtFree(src->ascii_src.string); + else + src->ascii_src.allocated_string = True; + + src->ascii_src.string = StorePiecesInString(src); + } +#ifdef OLDXAW + src->ascii_src.changes = False; +#else + src->text_src.changed = False; +#endif + + return (True); +} + +/* + * Function: + * XawAsciiSaveAsFile + * + * Arguments: + * w - AsciiSrc widget + * name - name of the file to save this file into + * + * Description: + * Save the current buffer as a file. + * + * Returns: + * True if the save was sucessful + */ +Bool +XawAsciiSaveAsFile(Widget w, _Xconst char *name) +{ + AsciiSrcObject src = (AsciiSrcObject)w; + Bool ret; + + /* If the src is really a multi, call the multi save */ + + if (XtIsSubclass( w, multiSrcObjectClass)) + return (_XawMultiSaveAsFile(w, name)); + + else if (!XtIsSubclass(w, asciiSrcObjectClass)) + XtErrorMsg("bad argument", "asciiSource", "XawError", + "XawAsciiSaveAsFile's 1st parameter must be an " + "asciiSrc or multiSrc.", + NULL, NULL); + + if (src->ascii_src.type == XawAsciiFile) + ret = WritePiecesToFile(src, (String)name); + else { + String string = StorePiecesInString(src); + + ret = WriteToFile(string, (String)name, src->ascii_src.length); + XtFree(string); + } + + return (ret); +} + +/* + * Function: + * XawAsciiSourceChanged + * + * Parameters: + * w - ascii source widget + * + * Description: + * Returns true if the source has changed since last saved. + * + * Returns: + * A Boolean (see description). + */ +Bool +XawAsciiSourceChanged(Widget w) +{ +#ifdef OLDXAW + if (XtIsSubclass(w, multiSrcObjectClass)) + return (((MultiSrcObject)w)->multi_src.changes); + + if (XtIsSubclass(w, asciiSrcObjectClass)) + return (((AsciiSrcObject)w)->ascii_src.changes); +#else + if (XtIsSubclass(w, textSrcObjectClass)) + return (((TextSrcObject)w)->textSrc.changed); +#endif + XtErrorMsg("bad argument", "asciiSource", "XawError", + "XawAsciiSourceChanged parameter must be an " + "asciiSrc or multiSrc.", + NULL, NULL); + + return (True); +} + +/* + * Private Functions + */ +static void +RemoveOldStringOrFile(AsciiSrcObject src, Bool checkString) +{ + FreeAllPieces(src); + + if (checkString && src->ascii_src.allocated_string) { + XtFree(src->ascii_src.string); + src->ascii_src.allocated_string = False; + src->ascii_src.string = NULL; + } +} + +/* + * Function: + * WriteToFile + * + * Parameters: + * string - string to write + * name - the name of the file + * + * Description: + * Write the string specified to the begining of the file specified. + * + * Returns: + * returns True if sucessful, False otherwise + */ +static Bool +WriteToFile(String string, String name, unsigned length) +{ + int fd; + + if ((fd = creat(name, 0666)) == -1) + return (False); + + if (write(fd, string, length) == -1) { + close(fd); + return (False); + } + + if (close(fd) == -1) + return (False); + + return (True); +} + +/* + * Function: + * WritePiecesToFile + * + * Parameters: + * src - ascii source object + * name - name of the file + * + * Description: + * Almost identical to WriteToFile, but only works for ascii src objects + * of type XawAsciiFile. This function avoids allocating temporary memory, + * what can be useful when editing very large files. + * + * Returns: + * returns True if sucessful, False otherwise + */ +static Bool +WritePiecesToFile(AsciiSrcObject src, String name) +{ + Piece *piece; + int fd; + + if (src->ascii_src.data_compression) { + Piece *tmp; + + piece = src->ascii_src.first_piece; + while (piece) { + int bytes = src->ascii_src.piece_size - piece->used; + + if (bytes > 0 && (tmp = piece->next) != NULL) { + bytes = XawMin(bytes, tmp->used); + memcpy(piece->text + piece->used, tmp->text, bytes); + memmove(tmp->text, tmp->text + bytes, tmp->used - bytes); + piece->used += bytes; + if ((tmp->used -= bytes) == 0) { + RemovePiece(src, tmp); + continue; + } + } + piece = piece->next; + } + } + + if ((fd = creat(name, 0666)) == -1) + return (False); + + for (piece = src->ascii_src.first_piece; piece; piece = piece->next) + if (write(fd, piece->text, piece->used) == -1) { + close(fd); + return (False); + } + + if (close(fd) == -1) + return (False); + + return (True); +} + +/* + * Function: + * StorePiecesInString + * + * Parameters: + * data - ascii pointer data + * + * Description: + * Store the pieces in memory into a standard ascii string. + */ +static String +StorePiecesInString(AsciiSrcObject src) +{ + String string; + XawTextPosition first; + Piece *piece; + + string = XtMalloc((unsigned)(src->ascii_src.length + 1)); + + for (first = 0, piece = src->ascii_src.first_piece ; piece != NULL; + first += piece->used, piece = piece->next) + memcpy(string + first, piece->text, (unsigned)piece->used); + + string[src->ascii_src.length] = '\0'; + + /* + * This will refill all pieces to capacity + */ + if (src->ascii_src.data_compression) { + FreeAllPieces(src); + LoadPieces(src, NULL, string); + } + + return (string); +} + +/* + * Function: + * InitStringOrFile + * + * Parameters: + * src - AsciiSource + * + * Description: + * Initializes the string or file. + */ +static FILE * +InitStringOrFile(AsciiSrcObject src, Bool newString) +{ + mode_t open_mode = 0; + const char *fdopen_mode = NULL; + int fd; + FILE *file; + + if (src->ascii_src.type == XawAsciiString) { + if (src->ascii_src.string == NULL) + src->ascii_src.length = 0; + + else if (!src->ascii_src.use_string_in_place) { + src->ascii_src.string = XtNewString(src->ascii_src.string); + src->ascii_src.allocated_string = True; + src->ascii_src.length = strlen(src->ascii_src.string); + } + + if (src->ascii_src.use_string_in_place) { + if (src->ascii_src.string != NULL) + src->ascii_src.length = strlen(src->ascii_src.string); + /* In case the length resource is incorrectly set */ + if (src->ascii_src.length > src->ascii_src.ascii_length) + src->ascii_src.ascii_length = src->ascii_src.length; + + if (src->ascii_src.ascii_length == MAGIC_VALUE) + src->ascii_src.piece_size = src->ascii_src.length; + else + src->ascii_src.piece_size = src->ascii_src.ascii_length + 1; + } + + return (NULL); + } + + /* + * type is XawAsciiFile + */ + src->ascii_src.is_tempfile = False; + + switch (src->text_src.edit_mode) { + case XawtextRead: + if (src->ascii_src.string == NULL) + XtErrorMsg("NoFile", "asciiSourceCreate", "XawError", + "Creating a read only disk widget and no file specified.", + NULL, NULL); + open_mode = O_RDONLY; + fdopen_mode = "r"; + break; + case XawtextAppend: + case XawtextEdit: + if (src->ascii_src.string == NULL) { + src->ascii_src.string = "*ascii-src*"; + src->ascii_src.is_tempfile = True; + } + else { +/* O_NOFOLLOW is a FreeBSD & Linux extension */ +#ifdef O_NOFOLLOW + open_mode = O_RDWR | O_NOFOLLOW; +#else + open_mode = O_RDWR; /* unsafe; subject to race conditions */ +#endif /* O_NOFOLLOW */ + fdopen_mode = "r+"; + } + break; + default: + XtErrorMsg("badMode", "asciiSourceCreate", "XawError", + "Bad editMode for ascii source; must be Read, " + "Append or Edit.", + NULL, NULL); + } + + /* If is_tempfile, allocate a private copy of the text + * Unlikely to be changed, just to set allocated_string */ + if (newString || src->ascii_src.is_tempfile) { + src->ascii_src.string = XtNewString(src->ascii_src.string); + src->ascii_src.allocated_string = True; + } + + if (!src->ascii_src.is_tempfile) { + if ((fd = open(src->ascii_src.string, open_mode, 0666)) != -1) { + if ((file = fdopen(fd, fdopen_mode))) { + (void)fseek(file, 0, SEEK_END); + src->ascii_src.length = (XawTextPosition)ftell(file); + return (file); + } + } + { + String params[2]; + Cardinal num_params = 2; + + params[0] = src->ascii_src.string; + params[1] = strerror(errno); + XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src), + "openError", "asciiSourceCreate", "XawWarning", + "Cannot open file %s; %s", params, &num_params); + } + } + src->ascii_src.length = 0; + return (NULL); +} + +static void +LoadPieces(AsciiSrcObject src, FILE *file, char *string) +{ + char *ptr; + Piece *piece = NULL; + XawTextPosition left; + + if (string == NULL) { + if (src->ascii_src.type == XawAsciiFile) { + if (src->ascii_src.length != 0) { + int len; + + left = 0; + fseek(file, 0, 0); + while (left < src->ascii_src.length) { + ptr = XtMalloc((unsigned)src->ascii_src.piece_size); + if ((len = fread(ptr, (Size_t)sizeof(unsigned char), + (Size_t)src->ascii_src.piece_size, file)) < 0) + XtErrorMsg("readError", "asciiSourceCreate", "XawError", + "fread returned error.", NULL, NULL); + piece = AllocNewPiece(src, piece); + piece->text = ptr; + piece->used = XawMin(len, src->ascii_src.piece_size); + left += piece->used; + } + } + else { + piece = AllocNewPiece(src, NULL); + piece->text = XtMalloc((unsigned)src->ascii_src.piece_size); + piece->used = 0; + } + return; + } + else + string = src->ascii_src.string; + } + + if (src->ascii_src.use_string_in_place) { + piece = AllocNewPiece(src, piece); + piece->used = XawMin(src->ascii_src.length, src->ascii_src.piece_size); + piece->text = src->ascii_src.string; + return; + } + + ptr = string; + left = src->ascii_src.length; + do { + piece = AllocNewPiece(src, piece); + + piece->text = XtMalloc((unsigned)src->ascii_src.piece_size); + piece->used = XawMin(left, src->ascii_src.piece_size); + if (piece->used != 0) + memcpy(piece->text, ptr, (unsigned)piece->used); + + left -= piece->used; + ptr += piece->used; + } while (left > 0); +} + +/* + * Function: + * AllocNewPiece + * + * Parameters: + * src - AsciiSrc Widget + * prev - piece just before this one, or NULL + * + * Description: + * Allocates a new piece of memory. + * + * Returns: + * The allocated piece + */ +static Piece * +AllocNewPiece(AsciiSrcObject src, Piece *prev) +{ + Piece *piece = XtNew(Piece); + + if (prev == NULL) { + src->ascii_src.first_piece = piece; + piece->next = NULL; + } + else { + if (prev->next != NULL) + (prev->next)->prev = piece; + piece->next = prev->next; + prev->next = piece; + } + + piece->prev = prev; + + return (piece); +} + +/* + * Function: + * FreeAllPieces + * + * Parameters: + * src - AsciiSrc Widget + * + * Description: + * Frees all the pieces. + */ +static void +FreeAllPieces(AsciiSrcObject src) +{ + Piece *next, * first = src->ascii_src.first_piece; + +#ifdef DEBUG + if (first->prev != NULL) + printf("Xaw AsciiSrc Object: possible memory leak in FreeAllPieces().\n"); +#endif + + for (; first != NULL ; first = next) { + next = first->next; + RemovePiece(src, first); + } +} + +/* + * Function: + * RemovePiece + * + * Parameters: + * piece - piece to remove + * + * Description: + * Removes a piece from the list. + */ +static void +RemovePiece(AsciiSrcObject src, Piece *piece) +{ + if (piece->prev == NULL) + src->ascii_src.first_piece = piece->next; + else + piece->prev->next = piece->next; + + if (piece->next != NULL) + piece->next->prev = piece->prev; + + if (!src->ascii_src.use_string_in_place) + XtFree(piece->text); + + XtFree((char *)piece); +} + +/* + * Function: + * FindPiece + * + * Parameters: + * src - AsciiSrc Widget + * position - position that we are searching for + * first - position of the first character in this piece (return) + * + * Description: + * Finds the piece containing the position indicated. + * + * Returns: + * the piece that contains this position + */ +static Piece * +FindPiece(AsciiSrcObject src, XawTextPosition position, XawTextPosition *first) +{ + Piece *old_piece, *piece; + XawTextPosition temp; + + for (old_piece = NULL, piece = src->ascii_src.first_piece, temp = 0; + piece; old_piece = piece, piece = piece->next) + if ((temp += piece->used) > position) { + *first = temp - piece->used; + return (piece); + } + + *first = temp - (old_piece ? old_piece->used : 0); + + return (old_piece); /* if we run off the end the return the last piece */ +} + +/* + * Function: + * BreakPiece + * + * Parameters: + * src - AsciiSrc Widget + * piece - piece to break + * + * Description: + * Breaks a full piece into two new pieces. + */ +#define HALF_PIECE (src->ascii_src.piece_size >> 1) +static void +BreakPiece(AsciiSrcObject src, Piece *piece) +{ + Piece *cnew = AllocNewPiece(src, piece); + + cnew->text = XtMalloc((unsigned)src->ascii_src.piece_size); + memcpy(cnew->text, piece->text + HALF_PIECE, + (unsigned)(src->ascii_src.piece_size - HALF_PIECE)); + piece->used = HALF_PIECE; + cnew->used = src->ascii_src.piece_size - HALF_PIECE; +} + +/*ARGSUSED*/ +static void +CvtStringToAsciiType(XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal) +{ + static XawAsciiType type; + XrmQuark q; + char name[7]; + + XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name)); + q = XrmStringToQuark(name); + + if (q == Qstring) + type = XawAsciiString; + else if (q == Qfile) + type = XawAsciiFile; + else { + toVal->size = 0; + toVal->addr = NULL; + XtStringConversionWarning((char *)fromVal->addr, XtRAsciiType); + } + + toVal->size = sizeof(XawAsciiType); + toVal->addr = (XPointer)&type; +} + +/*ARGSUSED*/ +static Boolean +CvtAsciiTypeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal, + XtPointer *data) +{ + static String buffer; + Cardinal size; + + switch (*(XawAsciiType *)fromVal->addr) { + case XawAsciiFile: + buffer = XtEfile; + break; + case XawAsciiString: + buffer = XtEstring; + break; + default: + XawTypeToStringWarning(dpy, XtRAsciiType); + toVal->addr = NULL; + toVal->size = 0; + return (False); + } + + size = strlen(buffer) + 1; + if (toVal->addr != NULL) { + if (toVal->size < size) { + toVal->size = size; + return (False); + } + strcpy((char *)toVal->addr, buffer); + } + else + toVal->addr = (XPointer)buffer; + toVal->size = sizeof(String); + + return (True); +} + +/*ARGSUSED*/ +static void +GetDefaultPieceSize(Widget w, int offset, XrmValue *value) +{ + static XPointer pagesize; + + if (pagesize == NULL) { + pagesize = (XPointer)((long)_XawGetPageSize()); + if (pagesize < (XPointer)BUFSIZ) + pagesize = (XPointer)BUFSIZ; + } + + value->addr = (XPointer)&pagesize; +} + +#if (defined(ASCII_STRING) || defined(ASCII_DISK)) +# include +#endif + +#ifdef ASCII_STRING +/* + * Compatability functions. + */ +/* + * Function: + * AsciiStringSourceCreate + * + * Parameters: + * parent - widget that will own this source + * args - the argument list + * num_args - "" + * + * Description: + * Creates a string source. + * + * Returns: + * A pointer to the new text source. + */ +Widget +XawStringSourceCreate(Widget parent, ArgList args, Cardinal num_args) +{ + XawTextSource src; + ArgList ascii_args; + Arg temp[2]; + + XtSetArg(temp[0], XtNtype, XawAsciiString); + XtSetArg(temp[1], XtNuseStringInPlace, True); + ascii_args = XtMergeArgLists(temp, TWO, args, num_args); + + src = XtCreateWidget("genericAsciiString", asciiSrcObjectClass, parent, + ascii_args, num_args + TWO); + XtFree((char *)ascii_args); + + return (src); +} + +/* + * This is hacked up to try to emulate old functionality, it + * may not work, as I have not old code to test it on. + * + * Chris D. Peterson 8/31/89. + */ +void +XawTextSetLastPos(Widget w, XawTextPosition lastPos) +{ + AsciiSrcObject src = (AsciiSrcObject)XawTextGetSource(w); + + src->ascii_src.piece_size = lastPos; +} +#endif /* ASCII_STRING */ + +#ifdef ASCII_DISK +/* + * Function: + * AsciiDiskSourceCreate + * + * Parameters: + * parent - widget that will own this source + * args - argument list + * num_args - "" + * + * Description: + * Creates a disk source. + * + * Returns: + * A pointer to the new text source + */ +Widget +XawDiskSourceCreate(Widget parent, ArgList args, Cardinal num_args) +{ + XawTextSource src; + ArgList ascii_args; + Arg temp[1]; + int i; + + XtSetArg(temp[0], XtNtype, XawAsciiFile); + ascii_args = XtMergeArgLists(temp, ONE, args, num_args); + num_args++; + + for (i = 0; i < num_args; i++) + if (streq(ascii_args[i].name, XtNfile) + || streq(ascii_args[i].name, XtCFile)) + ascii_args[i].name = XtNstring; + + src = XtCreateWidget("genericAsciiDisk", asciiSrcObjectClass, parent, + ascii_args, num_args); + XtFree((char *)ascii_args); + + return (src); +} +#endif /* ASCII_DISK */ diff --git a/src/AsciiText.c b/src/AsciiText.c new file mode 100644 index 0000000..8e2f0aa --- /dev/null +++ b/src/AsciiText.c @@ -0,0 +1,357 @@ +/* + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + +/* + * AsciiText.c - Source code for AsciiText Widget + * + * This Widget is intended to be used as a simple front end to the + * text widget with an ascii source and ascii sink attached to it + * + * Date: June 29, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#define TAB_COUNT 32 + +/* + * Class Methods + */ +static void XawAsciiInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawAsciiDestroy(Widget); + +/* + * From TextSrc.c + */ +void _XawSourceAddText(Widget, Widget); +void _XawSourceRemoveText(Widget, Widget, Bool); + +#define Superclass (&textClassRec) +AsciiTextClassRec asciiTextClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "Text", /* class_name */ + sizeof(AsciiRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + NULL, /* class_part_init */ + False, /* class_inited */ + XawAsciiInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + NULL, /* resources */ + 0, /* num_resource */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + XtExposeGraphicsExpose | /* compress_exposure */ + XtExposeNoExpose, + True, /* compress_enterleave */ + False, /* visible_interest */ + XawAsciiDestroy, /* destroy */ + XtInheritResize, /* resize */ + XtInheritExpose, /* expose */ + NULL, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + XtInheritAcceptFocus, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + XtInheritTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* text */ + { + NULL, /* extension */ + }, + /* ascii */ + { + NULL, /* extension */ + }, +}; + +WidgetClass asciiTextWidgetClass = (WidgetClass)&asciiTextClassRec; + +#ifdef ASCII_STRING +AsciiStringClassRec asciiStringClassRec = { + /* core */ + { + (WidgetClass)&asciiTextClassRec, /* superclass */ + "Text", /* class_name */ + sizeof(AsciiStringRec), /* widget_size */ + NULL, /* class_initialize */ + NULL, /* class_part_init */ + False, /* class_inited */ + NULL, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + NULL, /* resources */ + 0, /* num_resource */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + XtExposeGraphicsExpose | /* compress_exposure */ + XtExposeNoExpose, + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + XtInheritResize, /* resize */ + XtInheritExpose, /* expose */ + NULL, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + XtInheritAcceptFocus, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + XtInheritTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* text */ + { + NULL, /* extension */ + }, + /* ascii */ + { + NULL, /* extension */ + }, + /* string */ + { + NULL, /* extension */ + }, +}; + +WidgetClass asciiStringWidgetClass = (WidgetClass)&asciiStringClassRec; +#endif /* ASCII_STRING */ + +#ifdef ASCII_DISK +AsciiDiskClassRec asciiDiskClassRec = { + /* core */ + { + (WidgetClass)&asciiTextClassRec, /* superclass */ + "Text", /* class_name */ + sizeof(AsciiDiskRec), /* widget_size */ + NULL, /* class_initialize */ + NULL, /* class_part_init */ + False, /* class_inited */ + NULL, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + NULL, /* resources */ + 0, /* num_resource */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + XtExposeGraphicsExpose | /* compress_enterleave */ + XtExposeNoExpose, + False, /* visible_interest */ + NULL, /* destroy */ + XtInheritResize, /* resize */ + XtInheritExpose, /* expose */ + NULL, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + XtInheritAcceptFocus, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + XtInheritTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* text */ + { + NULL, /* extension */ + }, + /* ascii */ + { + NULL, /* extension */ + }, + /* disk */ + { + NULL, /* extension */ + }, +}; + +WidgetClass asciiDiskWidgetClass = (WidgetClass)&asciiDiskClassRec; +#endif /* ASCII_DISK */ + +/* + * Implementation + */ +static void +XawAsciiInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + AsciiWidget w = (AsciiWidget)cnew; + int i; + int tabs[TAB_COUNT], tab; + + MultiSinkObject sink; + + /* superclass Initialize can't set the following, + * as it didn't know the source or sink when it was called + */ + if (XtHeight(request) == DEFAULT_TEXT_HEIGHT) + XtHeight(cnew) = DEFAULT_TEXT_HEIGHT; + + /* This is the main change for internationalization */ + if (w->simple.international == True) { /* The multi* are international */ + if (w->text.sink == NULL) + w->text.sink = XtCreateWidget("textSink", multiSinkObjectClass, + cnew, args, *num_args); + else if (!XtIsSubclass(w->text.sink, multiSinkObjectClass)) + XtError("Sink object is not a subclass of multiSink"); + + if (w->text.source == NULL) + w->text.source = XtCreateWidget("textSource", multiSrcObjectClass, + cnew, args, *num_args); + else if (!XtIsSubclass(w->text.source, multiSrcObjectClass)) + XtError("Source object is not a subclass of multiSrc"); +#ifndef OLDXAW + else + _XawSourceAddText(w->text.source, cnew); +#endif + } + else { + if (w->text.sink == NULL) + w->text.sink = XtCreateWidget("textSink", asciiSinkObjectClass, + cnew, args, *num_args); + else if (!XtIsSubclass(w->text.source, asciiSinkObjectClass)) + XtError("Sink object is not a subclass of asciiSink"); + + if (w->text.source == NULL) + w->text.source = XtCreateWidget("textSource", asciiSrcObjectClass, + cnew, args, *num_args); + else if (!XtIsSubclass(w->text.source, asciiSrcObjectClass)) + XtError("Source object is not a subclass of asciiSrc"); +#ifndef OLDXAW + else + _XawSourceAddText(w->text.source, cnew); +#endif + } + + if (XtHeight(w) == DEFAULT_TEXT_HEIGHT) + XtHeight(w) = VMargins(w) + XawTextSinkMaxHeight(w->text.sink, 1); + + for (i = 0, tab = 0; i < TAB_COUNT; i++) + tabs[i] = (tab += 8); + + XawTextSinkSetTabs(w->text.sink, TAB_COUNT, tabs); + + XawTextDisableRedisplay(cnew); + XawTextEnableRedisplay(cnew); + + _XawImRegister(cnew); + + /* If we are using a MultiSink we need to tell the input method stuff */ + if (w->simple.international == True) { + Arg list[4]; + Cardinal ac = 0; + + sink = (MultiSinkObject)w->text.sink; + XtSetArg(list[ac], XtNfontSet, sink->multi_sink.fontset); ac++; + XtSetArg(list[ac], XtNinsertPosition, w->text.insertPos); ac++; + XtSetArg(list[ac], XtNforeground, sink->text_sink.foreground); ac++; + XtSetArg(list[ac], XtNbackground, sink->text_sink.background); ac++; + _XawImSetValues(cnew, list, ac); + } +} + +static void +XawAsciiDestroy(Widget w) +{ + AsciiWidget ascii = (AsciiWidget)w; + + _XawImUnregister(w); + + if (w == XtParent(ascii->text.sink)) + XtDestroyWidget(ascii->text.sink); + +#ifdef OLDXAW + if (w == XtParent(ascii->text.source)) + XtDestroyWidget(ascii->text.source); +#else + _XawSourceRemoveText(ascii->text.source, w, + ascii->text.source && + w == XtParent(ascii->text.source)); +#endif +} diff --git a/src/Box.c b/src/Box.c new file mode 100644 index 0000000..266fb08 --- /dev/null +++ b/src/Box.c @@ -0,0 +1,673 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include "Private.h" + +/* + * Class Methods + */ +static void XawBoxChangeManaged(Widget); +static void XawBoxClassInitialize(void); +#ifndef OLDXAW +static void XawBoxExpose(Widget, XEvent*, Region); +#endif +static XtGeometryResult XawBoxGeometryManager(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawBoxInitialize(Widget, Widget, ArgList, Cardinal*); +static XtGeometryResult XawBoxQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawBoxRealize(Widget, Mask*, XSetWindowAttributes*); +static void XawBoxResize(Widget); +static Boolean XawBoxSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * Prototypes + */ +static void DoLayout(BoxWidget, unsigned int, unsigned int, + Dimension*, Dimension*, Bool); +static Bool TryNewLayout(BoxWidget); + +/* + * Initialization + */ +#ifndef OLDXAW +static XtActionsRec actions[] = { + {"set-values", XawSetValuesAction}, + {"get-values", XawGetValuesAction}, + {"declare", XawDeclareAction}, + {"call-proc", XawCallProcAction}, +}; +#endif + +static XtResource resources[] = { + { + XtNhSpace, + XtCHSpace, + XtRDimension, + sizeof(Dimension), + XtOffsetOf(BoxRec, box.h_space), + XtRImmediate, + (XtPointer)4 + }, + { + XtNvSpace, + XtCVSpace, + XtRDimension, + sizeof(Dimension), + XtOffsetOf(BoxRec, box.v_space), + XtRImmediate, + (XtPointer)4 + }, + { + XtNorientation, + XtCOrientation, + XtROrientation, + sizeof(XtOrientation), + XtOffsetOf(BoxRec, box.orientation), + XtRImmediate, + (XtPointer)XtorientVertical + }, +#ifndef OLDXAW + { + XawNdisplayList, + XawCDisplayList, + XawRDisplayList, + sizeof(XawDisplayList*), + XtOffsetOf(BoxRec, box.display_list), + XtRImmediate, + NULL + }, +#endif +}; + +BoxClassRec boxClassRec = { + /* core */ + { + (WidgetClass)&compositeClassRec, /* superclass */ + "Box", /* class_name */ + sizeof(BoxRec), /* widget_size */ + XawBoxClassInitialize, /* class_initialize */ + NULL, /* class_part_init */ + False, /* class_inited */ + XawBoxInitialize, /* initialize */ + NULL, /* initialize_hook */ + XawBoxRealize, /* realize */ +#ifndef OLDXAW + actions, /* actions */ + XtNumber(actions), /* num_actions */ +#else + NULL, /* actions */ + 0, /* num_actions */ +#endif + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + XawBoxResize, /* resize */ +#ifndef OLDXAW + XawBoxExpose, /* expose */ +#else + NULL, /* expose */ +#endif + XawBoxSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XawBoxQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* composite */ + { + XawBoxGeometryManager, /* geometry_manager */ + XawBoxChangeManaged, /* change_managed */ + XtInheritInsertChild, /* insert_child */ + XtInheritDeleteChild, /* delete_child */ + NULL, /* extension */ + }, + /* box */ + { + NULL, /* extension */ + }, +}; + +WidgetClass boxWidgetClass = (WidgetClass)&boxClassRec; + +/* + * Do a layout, either actually assigning positions, or just calculating size. + * Returns minimum width and height that will preserve the same layout. + */ +static void +DoLayout(BoxWidget bbw, unsigned int width, unsigned int height, + Dimension *reply_width, Dimension *reply_height, Bool position) +{ + Boolean vbox = (bbw->box.orientation == XtorientVertical); + Cardinal i; + Dimension w, h; /* Width and height needed for box */ + Dimension lw, lh; /* Width and height needed for current line */ + Dimension bw, bh; /* Width and height needed for current widget */ + Dimension h_space; /* Local copy of bbw->box.h_space */ + Widget widget; /* Current widget */ + unsigned int num_mapped_children = 0; + + /* Box width and height */ + h_space = bbw->box.h_space; + + w = 0; + for (i = 0; i < bbw->composite.num_children; i++) { + if (XtIsManaged(bbw->composite.children[i]) + && bbw->composite.children[i]->core.width > w) + w = bbw->composite.children[i]->core.width; + } + w += h_space; + if (w > width) + width = w; + h = bbw->box.v_space; + + /* Line width and height */ + lh = 0; + lw = h_space; + + for (i = 0; i < bbw->composite.num_children; i++) { + widget = bbw->composite.children[i]; + if (widget->core.managed) { + if (widget->core.mapped_when_managed) + num_mapped_children++; + /* Compute widget width */ + bw = XtWidth(widget) + (XtBorderWidth(widget)<<1) + h_space; + if ((Dimension)(lw + bw) > width) { + if (lw > h_space) { + /* At least one widget on this line, and + * can't fit any more. Start new line if vbox + */ + AssignMax(w, lw); + if (vbox) { + h += lh + bbw->box.v_space; + lh = 0; + lw = h_space; + } + } + else if (!position) { + /* too narrow for this widget; we'll assume we can grow */ + DoLayout(bbw, (unsigned)(lw + bw), height, reply_width, + reply_height, position); + return; + } + } + if (position && (lw != XtX(widget) || h != XtY(widget))) { + /* It would be nice to use window gravity, but there isn't + * sufficient fine-grain control to nicely handle all + * situations (e.g. when only the height changes -- + * a common case). Explicit unmapping is a cheap hack + * to speed things up & avoid the visual jitter as + * things slide around. + * + * %%% perhaps there should be a client resource to + * control this. If so, we'll have to optimize to + * perform the moves from the correct end so we don't + * force extra exposures as children occlude each other. + */ + if (XtIsRealized(widget) && widget->core.mapped_when_managed) + XUnmapWindow( XtDisplay(widget), XtWindow(widget)); + XtMoveWidget(widget, (int)lw, (int)h); + } + lw += bw; + bh = XtHeight(widget) + (XtBorderWidth(widget) << 1); + AssignMax(lh, bh); + } + } + + if (!vbox && width && lw > width && lh < height) { + /* reduce width if too wide and height not filled */ + Dimension sw = lw, sh = lh; + Dimension width_needed = width; + XtOrientation orientation = bbw->box.orientation; + + bbw->box.orientation = XtorientVertical; + while (sh < height && sw > width) { + width_needed = sw; + DoLayout(bbw, (unsigned)(sw-1), height, &sw, &sh, False); + } + if (sh < height) + width_needed = sw; + if (width_needed != lw) { + DoLayout(bbw, width_needed, height, + reply_width, reply_height, position); + bbw->box.orientation = orientation; + return; + } + bbw->box.orientation = orientation; + } + if (vbox && (width < w || width < lw)) { + AssignMax(w, lw); + DoLayout(bbw, w, height, reply_width, reply_height, position); + return; + } + if (position && XtIsRealized((Widget)bbw)) { + if (bbw->composite.num_children == num_mapped_children) + XMapSubwindows(XtDisplay((Widget)bbw), XtWindow((Widget)bbw)); + else { + int ii = bbw->composite.num_children; + Widget *childP = bbw->composite.children; + + for (; ii > 0; childP++, ii--) + if (XtIsRealized(*childP) && XtIsManaged(*childP) + && (*childP)->core.mapped_when_managed) + XtMapWidget(*childP); + } + } + + /* Finish off last line */ + if (lw > h_space) { + AssignMax(w, lw); + h += lh + bbw->box.v_space; + } + + *reply_width = Max(w, 1); + *reply_height = Max(h, 1); +} + +/* + * Calculate preferred size, given constraining box, caching it in the widget + */ +static XtGeometryResult +XawBoxQueryGeometry(Widget widget, XtWidgetGeometry *constraint, + XtWidgetGeometry *preferred) +{ + BoxWidget w = (BoxWidget)widget; + Dimension width; + Dimension preferred_width = w->box.preferred_width; + Dimension preferred_height = w->box.preferred_height; + + constraint->request_mode &= CWWidth | CWHeight; + + if (constraint->request_mode == 0) + /* parent isn't going to change w or h, so nothing to re-compute */ + return (XtGeometryYes); + + if (constraint->request_mode == w->box.last_query_mode + && (!(constraint->request_mode & CWWidth) + || constraint->width == w->box.last_query_width) + && (!(constraint->request_mode & CWHeight) + || constraint->height == w->box.last_query_height)) { + /* same query; current preferences are still valid */ + preferred->request_mode = CWWidth | CWHeight; + preferred->width = preferred_width; + preferred->height = preferred_height; + if (constraint->request_mode == (CWWidth | CWHeight) + && constraint->width == preferred_width + && constraint->height == preferred_height) + return (XtGeometryYes); + else + return (XtGeometryAlmost); + } + + /* else gotta do it the long way... + I have a preference for tall and narrow, so if my width is + constrained, I'll accept it; otherwise, I'll compute the minimum + width that will fit me within the height constraint */ + + w->box.last_query_mode = constraint->request_mode; + w->box.last_query_width = constraint->width; + w->box.last_query_height= constraint->height; + + if (constraint->request_mode & CWWidth) + width = constraint->width; + else { /* if (constraint->request_mode & CWHeight) */ + /* let's see if I can become any narrower */ + width = 0; + constraint->width = 65535; + } + + /* height is currently ignored by DoLayout. + height = (constraint->request_mode & CWHeight) ? constraint->height + : *preferred_height; + */ + DoLayout(w, width, 0, &preferred_width, &preferred_height, False); + + if (constraint->request_mode & CWHeight + && preferred_height > constraint->height) { + /* find minimum width for this height */ + if (preferred_width <= constraint->width) { + width = preferred_width; + do { /* find some width big enough to stay within this height */ + if (width > (constraint->width >> 1)) /* avoid short int overflow */ + width = constraint->width; + else + width <<= 1; + DoLayout(w, width, 0, &preferred_width, &preferred_height, False); + } while (preferred_height > constraint->height + && width < constraint->width); + if (width != constraint->width) { + do { /* find minimum width */ + width = preferred_width; + DoLayout(w, (unsigned)(preferred_width - 1), 0, + &preferred_width, &preferred_height, False); + } while (preferred_height < constraint->height); + /* one last time */ + DoLayout(w, width, 0, &preferred_width, &preferred_height, False); + } + } + } + + preferred->request_mode = CWWidth | CWHeight; + preferred->width = w->box.preferred_width = preferred_width; + preferred->height = w->box.preferred_height = preferred_height; + + if (constraint->request_mode == (CWWidth|CWHeight) + && constraint->width == preferred_width + && constraint->height == preferred_height) + return (XtGeometryYes); + + return (XtGeometryAlmost); +} + +/* + * Actually layout the box + */ +static void +XawBoxResize(Widget w) +{ + Dimension tmp; + + DoLayout((BoxWidget)w, XtWidth(w), XtHeight(w), &tmp, &tmp, True); +} + +/* + * Try to do a new layout within the current width and height; + * if that fails try to resize and do it within the box returne + * by XawBoxQueryGeometry + * + * TryNewLayout just says if it's possible, and doesn't actually move the kids + */ +static Bool +TryNewLayout(BoxWidget bbw) +{ + Dimension preferred_width, preferred_height; + Dimension proposed_width, proposed_height; + int iterations; + + DoLayout(bbw, bbw->core.width, bbw->core.height, + &preferred_width, &preferred_height, False); + + /* at this point, preferred_width is guaranteed to not be greater + than bbw->core.width unless some child is larger, so there's no + point in re-computing another layout */ + + if (XtWidth(bbw) == preferred_width && XtHeight(bbw) == preferred_height) + return (True); + + /* let's see if our parent will go for a new size */ + iterations = 0; + proposed_width = preferred_width; + proposed_height = preferred_height; + do { + switch (XtMakeResizeRequest((Widget)bbw,proposed_width,proposed_height, + &proposed_width, &proposed_height)) { + case XtGeometryYes: + return (True); + case XtGeometryNo: + if (iterations > 0) + /* protect from malicious parents who change their minds */ + DoLayout(bbw, bbw->core.width, bbw->core.height, + &preferred_width, &preferred_height, False); + if (preferred_width <= XtWidth(bbw) + && preferred_height <= XtHeight(bbw)) + return (True); + else + return (False); + case XtGeometryAlmost: + if (proposed_height >= preferred_height && + proposed_width >= preferred_width) { + /* + * Take it, and assume the parent knows what it is doing. + * + * The parent must accept this since it was returned in + * almost. + */ + (void)XtMakeResizeRequest((Widget)bbw, + proposed_width, proposed_height, + &proposed_width, &proposed_height); + return (True); + } + else if (proposed_width != preferred_width) { + /* recalc bounding box; height might change */ + DoLayout(bbw, proposed_width, 0, + &preferred_width, &preferred_height, False); + proposed_height = preferred_height; + } + else { /* proposed_height != preferred_height */ + XtWidgetGeometry constraints, reply; + + constraints.request_mode = CWHeight; + constraints.height = proposed_height; + (void)XawBoxQueryGeometry((Widget)bbw, &constraints, &reply); + proposed_width = preferred_width; + } + /*FALLTHROUGH*/ + default: + break; + } + iterations++; + } while (iterations < 10); + + return (False); +} + +/* + * Geometry Manager + * + * 'reply' is unused; we say only yeay or nay, never almost. + */ +/*ARGSUSED*/ +static XtGeometryResult +XawBoxGeometryManager(Widget w, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + Dimension width, height, borderWidth; + BoxWidget bbw; + + /* Position request always denied */ + if (((request->request_mode & CWX) && request->x != XtX(w)) + || ((request->request_mode & CWY) && request->y != XtY(w))) + return (XtGeometryNo); + + /* Size changes must see if the new size can be accomodated */ + if (request->request_mode & (CWWidth | CWHeight | CWBorderWidth)) { + /* Make all three fields in the request valid */ + if ((request->request_mode & CWWidth) == 0) + request->width = XtWidth(w); + if ((request->request_mode & CWHeight) == 0) + request->height = XtHeight(w); + if ((request->request_mode & CWBorderWidth) == 0) + request->border_width = XtBorderWidth(w); + + /* Save current size and set to new size */ + width = XtWidth(w); + height = XtHeight(w); + borderWidth = XtBorderWidth(w); + XtWidth(w) = request->width; + XtHeight(w) = request->height; + XtBorderWidth(w) = request->border_width; + + /* Decide if new layout works: + (1) new widget is smaller, + (2) new widget fits in existing Box, + (3) Box can be expanded to allow new widget to fit + */ + + bbw = (BoxWidget) w->core.parent; + + if (TryNewLayout(bbw)) { + /* Fits in existing or new space, relayout */ + (*XtClass((Widget)bbw)->core_class.resize)((Widget)bbw); + return (XtGeometryYes); + } + else { + /* Cannot satisfy request, change back to original geometry */ + XtWidth(w) = width; + XtHeight(w) = height; + XtBorderWidth(w) = borderWidth; + return (XtGeometryNo); + } + } + + /* Any stacking changes don't make a difference, so allow if that's all */ + return (XtGeometryYes); +} + +static void +XawBoxChangeManaged(Widget w) +{ + /* Reconfigure the box */ + (void)TryNewLayout((BoxWidget)w); + XawBoxResize(w); +} + +static void +XawBoxClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtAddConverter(XtRString, XtROrientation, XmuCvtStringToOrientation, + NULL, 0); + XtSetTypeConverter(XtROrientation, XtRString, XmuCvtOrientationToString, + NULL, 0, XtCacheNone, NULL); +} + +/*ARGSUSED*/ +static void +XawBoxInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + BoxWidget newbbw = (BoxWidget)cnew; + + newbbw->box.last_query_mode = CWWidth | CWHeight; + newbbw->box.last_query_width = newbbw->box.last_query_height = 0; + newbbw->box.preferred_width = Max(newbbw->box.h_space, 1); + newbbw->box.preferred_height = Max(newbbw->box.v_space, 1); + + if (XtWidth(newbbw) == 0) + XtWidth(newbbw) = newbbw->box.preferred_width; + + if (XtHeight(newbbw) == 0) + XtHeight(newbbw) = newbbw->box.preferred_height; +} + +static void +XawBoxRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) +{ +#ifndef OLDXAW + XawPixmap *pixmap; +#endif + + XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent, + *valueMask, attributes); + +#ifndef OLDXAW + if (w->core.background_pixmap > XtUnspecifiedPixmap) { + pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w), + w->core.colormap, w->core.depth); + if (pixmap && pixmap->mask) + XawReshapeWidget(w, pixmap); + } +#endif +} + +/*ARGSUSED*/ +static Boolean +XawBoxSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + /* need to relayout if h_space or v_space change */ +#ifndef OLDXAW + BoxWidget b_old = (BoxWidget)current; + BoxWidget b_new = (BoxWidget)cnew; + + if (b_old->core.background_pixmap != b_new->core.background_pixmap) { + XawPixmap *opix, *npix; + + opix = XawPixmapFromXPixmap(b_old->core.background_pixmap, + XtScreen(b_old), b_old->core.colormap, + b_old->core.depth); + npix = XawPixmapFromXPixmap(b_new->core.background_pixmap, + XtScreen(b_new), b_new->core.colormap, + b_new->core.depth); + if ((npix && npix->mask) || (opix && opix->mask)) + XawReshapeWidget(cnew, npix); + } +#endif /* OLDXAW */ + + return (False); +} + +#ifndef OLDXAW +static void +XawBoxExpose(Widget w, XEvent *event, Region region) +{ + BoxWidget xaw = (BoxWidget)w; + + if (xaw->box.display_list) + XawRunDisplayList(w, xaw->box.display_list, event, region); +} +#endif /* OLDXAW */ diff --git a/src/Command.c b/src/Command.c new file mode 100644 index 0000000..4535423 --- /dev/null +++ b/src/Command.c @@ -0,0 +1,657 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Command.c - Command button widget + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#define DEFAULT_HIGHLIGHT_THICKNESS 2 +#define DEFAULT_SHAPE_HIGHLIGHT 32767 +#define STR_EQUAL(str1, str2) (str1 == str2 || strcmp(str1, str2) == 0) + +/* + * Class Methods + */ +static void XawCommandClassInitialize(void); +static void XawCommandDestroy(Widget); +static void XawCommandInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawCommandRealize(Widget, Mask*, XSetWindowAttributes*); +static void XawCommandResize(Widget); +static void XawCommandRedisplay(Widget, XEvent*, Region); +static Boolean XawCommandSetValues(Widget, Widget, Widget, ArgList, Cardinal*); +static void XawCommandGetValuesHook(Widget, ArgList, Cardinal*); +static Bool ChangeSensitive(Widget); + +/* + * Prototypes + */ +static GC Get_GC(CommandWidget, Pixel, Pixel); +static void PaintCommandWidget(Widget, XEvent*, Region, Bool); +static Region HighlightRegion(CommandWidget); +static Bool ShapeButton(CommandWidget, Bool); +static void XawCommandToggle(Widget); + +/* + * Actions + */ +static void Highlight(Widget, XEvent*, String*, Cardinal*); +static void Notify(Widget, XEvent*, String*, Cardinal*); +static void Reset(Widget, XEvent*, String*, Cardinal*); +static void Set(Widget, XEvent*, String*, Cardinal*); +static void Unhighlight(Widget, XEvent*, String*, Cardinal*); +static void Unset(Widget, XEvent*, String*, Cardinal*); + +/* + * Initialization + */ +static char defaultTranslations[] = +":" "highlight()\n" +":" "reset()\n" +":" "set()\n" +":" "notify() unset()\n" +; + +#define offset(field) XtOffsetOf(CommandRec, field) +static XtResource resources[] = { + { + XtNcallback, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + offset(command.callbacks), + XtRCallback, + NULL + }, + { + XtNhighlightThickness, + XtCThickness, + XtRDimension, + sizeof(Dimension), + offset(command.highlight_thickness), + XtRImmediate, + (XtPointer)DEFAULT_SHAPE_HIGHLIGHT + }, + { + XtNshapeStyle, + XtCShapeStyle, + XtRShapeStyle, + sizeof(int), + offset(command.shape_style), + XtRImmediate, + (XtPointer)XawShapeRectangle + }, + { + XtNcornerRoundPercent, + XtCCornerRoundPercent, + XtRDimension, + sizeof(Dimension), + offset(command.corner_round), + XtRImmediate, + (XtPointer)25 + }, +}; +#undef offset + +static XtActionsRec actionsList[] = { + {"set", Set}, + {"notify", Notify}, + {"highlight", Highlight}, + {"reset", Reset}, + {"unset", Unset}, + {"unhighlight", Unhighlight} +}; + +#define SuperClass ((LabelWidgetClass)&labelClassRec) + +CommandClassRec commandClassRec = { + /* core */ + { + (WidgetClass)SuperClass, /* superclass */ + "Command", /* class_name */ + sizeof(CommandRec), /* size */ + XawCommandClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawCommandInitialize, /* initialize */ + NULL, /* initialize_hook */ + XawCommandRealize, /* realize */ + actionsList, /* actions */ + XtNumber(actionsList), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawCommandDestroy, /* destroy */ + XawCommandResize, /* resize */ + XawCommandRedisplay, /* expose */ + XawCommandSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + XawCommandGetValuesHook, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + defaultTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + ChangeSensitive, /* change_sensitive */ + }, + /* label */ + { + NULL, /* not used */ + }, + /* command */ + { + NULL, /* not used */ + }, +}; + +WidgetClass commandWidgetClass = (WidgetClass)&commandClassRec; + +/* + * Implementation + */ +static GC +Get_GC(CommandWidget cbw, Pixel fg, Pixel bg) +{ + XGCValues values; + + values.foreground = fg; + values.background = bg; + values.font = cbw->label.font->fid; + values.cap_style = CapProjecting; + + if (cbw->command.highlight_thickness > 1) + values.line_width = cbw->command.highlight_thickness; + else + values.line_width = 0; + + if (cbw->simple.international == True) + return (XtAllocateGC((Widget)cbw, 0, + GCForeground | GCBackground | GCLineWidth | + GCCapStyle, &values, GCFont, 0)); + else + return (XtGetGC((Widget)cbw, + GCForeground | GCBackground | GCFont | GCLineWidth | + GCCapStyle, &values)); +} + +/*ARGSUSED*/ +static void +XawCommandInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + CommandWidget cbw = (CommandWidget)cnew; + int shape_event_base, shape_error_base; + + if (!cbw->label.font) XtError("Aborting: no font found\n"); + + if (cbw->command.shape_style != XawShapeRectangle && + !XShapeQueryExtension(XtDisplay(cnew), &shape_event_base, + &shape_error_base)) + cbw->command.shape_style = XawShapeRectangle; + + if (cbw->command.highlight_thickness == DEFAULT_SHAPE_HIGHLIGHT) { + if (cbw->command.shape_style != XawShapeRectangle) + cbw->command.highlight_thickness = 0; + else + cbw->command.highlight_thickness = DEFAULT_HIGHLIGHT_THICKNESS; + } + + cbw->command.normal_GC = Get_GC(cbw, cbw->label.foreground, + cbw->core.background_pixel); + cbw->command.inverse_GC = Get_GC(cbw, cbw->core.background_pixel, + cbw->label.foreground); + XtReleaseGC(cnew, cbw->label.normal_GC); + cbw->label.normal_GC = cbw->command.normal_GC; + + cbw->command.set = False; + cbw->command.highlighted = HighlightNone; +} + +static Region +HighlightRegion(CommandWidget cbw) +{ + static Region outerRegion = NULL, innerRegion, emptyRegion; + XRectangle rect; + + if (cbw->command.highlight_thickness == 0 || + cbw->command.highlight_thickness > Min(XtWidth(cbw), XtHeight(cbw)) / 2) + return (NULL); + + if (outerRegion == NULL) { + /* save time by allocating scratch regions only once. */ + outerRegion = XCreateRegion(); + innerRegion = XCreateRegion(); + emptyRegion = XCreateRegion(); + } + + rect.x = rect.y = 0; + rect.width = XtWidth(cbw); + rect.height = XtHeight(cbw); + XUnionRectWithRegion(&rect, emptyRegion, outerRegion); + rect.x = rect.y = cbw->command.highlight_thickness; + rect.width -= cbw->command.highlight_thickness * 2; + rect.height -= cbw->command.highlight_thickness * 2; + XUnionRectWithRegion(&rect, emptyRegion, innerRegion); + XSubtractRegion(outerRegion, innerRegion, outerRegion); + + return (outerRegion); +} + +/*************************** +* Action Procedures +***************************/ +static void +XawCommandToggle(Widget w) +{ + CommandWidget xaw = (CommandWidget)w; + Arg args[2]; + Cardinal num_args; + + num_args = 0; + XtSetArg(args[num_args], XtNbackground, + xaw->label.foreground); ++num_args; + XtSetArg(args[num_args], XtNforeground, + xaw->core.background_pixel); ++num_args; + XtSetValues(w, args, num_args); +} + +/*ARGSUSED*/ +static void +Set(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + CommandWidget cbw = (CommandWidget)w; + + if (cbw->command.set) + return; + + XawCommandToggle(w); + cbw->command.set= True; +} + +/*ARGSUSED*/ +static void +Unset(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + CommandWidget cbw = (CommandWidget)w; + + if (!cbw->command.set) + return; + + cbw->command.set = False; + XawCommandToggle(w); +} + +/*ARGSUSED*/ +static void +Reset(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + CommandWidget cbw = (CommandWidget)w; + + if (cbw->command.set) { + cbw->command.highlighted = HighlightNone; + Unset(w, event, params, num_params); + } + else + Unhighlight(w, event, params, num_params); +} + +/*ARGSUSED*/ +static void +Highlight(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + CommandWidget cbw = (CommandWidget)w; + + if (*num_params == (Cardinal)0) + cbw->command.highlighted = HighlightWhenUnset; + else { + if (*num_params != (Cardinal)1) + XtWarning("Too many parameters passed to highlight action table."); + switch (params[0][0]) { + case 'A': + case 'a': + cbw->command.highlighted = HighlightAlways; + break; + default: + cbw->command.highlighted = HighlightWhenUnset; + break; + } + } + + if (XtIsRealized(w)) + PaintCommandWidget(w, event, HighlightRegion(cbw), True); +} + +/*ARGSUSED*/ +static void +Unhighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + CommandWidget cbw = (CommandWidget)w; + + cbw->command.highlighted = HighlightNone; + if (XtIsRealized(w)) + PaintCommandWidget(w, event, HighlightRegion(cbw), True); +} + +/*ARGSUSED*/ +static void +Notify(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + CommandWidget cbw = (CommandWidget)w; + + /* check to be sure state is still Set so that user can cancel + the action (e.g. by moving outside the window, in the default + bindings. + */ + if (cbw->command.set) + XtCallCallbackList(w, cbw->command.callbacks, (XtPointer) NULL); +} + +static void +XawCommandRedisplay(Widget w, XEvent *event, Region region) +{ + PaintCommandWidget(w, event, region, False); +} + +/* + * Function: + * PaintCommandWidget + * Parameters: + * w - command widget + * region - region to paint (passed to the superclass) + * change - did it change either set or highlight state? + */ +static void +PaintCommandWidget(Widget w, XEvent *event, Region region, Bool change) +{ + CommandWidget cbw = (CommandWidget)w; + Bool very_thick; + GC rev_gc; + + very_thick = cbw->command.highlight_thickness + > Min(XtWidth(cbw), XtHeight(cbw)) / 2; + + if (cbw->command.highlight_thickness == 0) { + (*SuperClass->core_class.expose) (w, event, region); + return; + } + + /* + * If we are set then use the same colors as if we are not highlighted + */ + + if (cbw->command.highlighted != HighlightNone) { + rev_gc = cbw->command.normal_GC; + } + else { + rev_gc = cbw->command.inverse_GC; + } + + if (!((!change && cbw->command.highlighted == HighlightNone) + || (cbw->command.highlighted == HighlightWhenUnset + && cbw->command.set))) { + if (very_thick) + XFillRectangle(XtDisplay(w),XtWindow(w), rev_gc, + 0, 0, XtWidth(cbw), XtHeight(cbw)); + else { + /* wide lines are centered on the path, so indent it */ + if (cbw->core.background_pixmap != XtUnspecifiedPixmap && + rev_gc == cbw->command.inverse_GC) { + XClearArea(XtDisplay(w), XtWindow(w), + 0, 0, XtWidth(cbw), cbw->command.highlight_thickness, + False); + XClearArea(XtDisplay(w), XtWindow(w), + 0, cbw->command.highlight_thickness, + cbw->command.highlight_thickness, + XtHeight(cbw) - (cbw->command.highlight_thickness<<1), + False); + XClearArea(XtDisplay(w), XtWindow(w), + XtWidth(cbw) - cbw->command.highlight_thickness, + cbw->command.highlight_thickness, + cbw->command.highlight_thickness, + XtHeight(cbw) - (cbw->command.highlight_thickness<<1), + False); + XClearArea(XtDisplay(w), XtWindow(w), + 0, XtHeight(cbw) - cbw->command.highlight_thickness, + XtWidth(cbw), cbw->command.highlight_thickness, + False); + } + else { + int offset = cbw->command.highlight_thickness / 2; + + XDrawRectangle(XtDisplay(w),XtWindow(w), rev_gc, offset, offset, + XtWidth(cbw) - cbw->command.highlight_thickness, + XtHeight(cbw) - cbw->command.highlight_thickness); + } + } + } + + (*SuperClass->core_class.expose)(w, event, region); +} + +static void +XawCommandDestroy(Widget w) +{ + CommandWidget cbw = (CommandWidget)w; + + /* Label will release cbw->command.normal_GC */ + XtReleaseGC(w, cbw->command.inverse_GC); +} + +/*ARGSUSED*/ +static Boolean +XawCommandSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + CommandWidget oldcbw = (CommandWidget)current; + CommandWidget cbw = (CommandWidget)cnew; + Boolean redisplay = False; + + if (oldcbw->core.sensitive != cbw->core.sensitive && !cbw->core.sensitive) { + cbw->command.highlighted = HighlightNone; + redisplay = True; + } + + if (cbw->command.set) { + unsigned int i; + Pixel foreground, background; + + foreground = oldcbw->label.foreground; + background = oldcbw->core.background_pixel; + for (i = 0; i < *num_args; i++) { + if (STR_EQUAL(args[i].name, XtNforeground)) + background = cbw->label.foreground; + else if (STR_EQUAL(args[i].name, XtNbackground)) + foreground = cbw->core.background_pixel; + } + cbw->label.foreground = foreground; + cbw->core.background_pixel = background; + } + + if (oldcbw->label.foreground != cbw->label.foreground + || oldcbw->core.background_pixel != cbw->core.background_pixel + || oldcbw->command.highlight_thickness + != cbw->command.highlight_thickness + || oldcbw->label.font != cbw->label.font) { + XtReleaseGC(cnew, cbw->command.inverse_GC); + + cbw->command.normal_GC = Get_GC(cbw, cbw->label.foreground, + cbw->core.background_pixel); + cbw->command.inverse_GC = Get_GC(cbw, cbw->core.background_pixel, + cbw->label.foreground); + XtReleaseGC(cnew, cbw->label.normal_GC); + cbw->label.normal_GC = cbw->command.normal_GC; + + redisplay = True; + } + + if (XtIsRealized(cnew) + && oldcbw->command.shape_style != cbw->command.shape_style + && !ShapeButton(cbw, True)) + cbw->command.shape_style = oldcbw->command.shape_style; + + return (redisplay); +} + +static void +XawCommandGetValuesHook(Widget w, ArgList args, Cardinal *num_args) +{ + CommandWidget cbw = (CommandWidget)w; + unsigned int i; + + for (i = 0; i < *num_args; i++) { + if (STR_EQUAL(args[i].name, XtNforeground)) + *((String*)args[i].value) = cbw->command.set ? + (String)cbw->core.background_pixel : (String)cbw->label.foreground; + else if (STR_EQUAL(args[i].name, XtNbackground)) + *((String*)args[i].value) = cbw->command.set ? + (String)cbw->label.foreground : (String)cbw->core.background_pixel; + } +} + +static void +XawCommandClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtSetTypeConverter(XtRString, XtRShapeStyle, XmuCvtStringToShapeStyle, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRShapeStyle, XtRString, XmuCvtShapeStyleToString, + NULL, 0, XtCacheNone, NULL); +} + +static Bool +ShapeButton(CommandWidget cbw, Bool checkRectangular) +{ + Dimension corner_size = 0; + + if (cbw->command.shape_style == XawShapeRoundedRectangle) { + corner_size = XtWidth(cbw) < XtHeight(cbw) ? + XtWidth(cbw) : XtHeight(cbw); + corner_size = (corner_size * cbw->command.corner_round) / 100; + } + + if (checkRectangular || cbw->command.shape_style != XawShapeRectangle) { + if (!XmuReshapeWidget((Widget)cbw, cbw->command.shape_style, + corner_size, corner_size)) { + cbw->command.shape_style = XawShapeRectangle; + return (False); + } + } + + return (True); +} + +static void +XawCommandRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) +{ + (*commandWidgetClass->core_class.superclass->core_class.realize) + (w, valueMask, attributes); + + ShapeButton((CommandWidget)w, False); +} + +static void +XawCommandResize(Widget w) +{ + if (XtIsRealized(w)) + ShapeButton((CommandWidget)w, False); + + (*commandWidgetClass->core_class.superclass->core_class.resize)(w); +} + +static Bool +ChangeSensitive(Widget w) +{ + CommandWidget cbw = (CommandWidget)w; + + if (XtIsRealized(w)) { + if (XtIsSensitive(w)) { + if (w->core.border_pixmap != XtUnspecifiedPixmap) + XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w), + w->core.border_pixmap); + else + XSetWindowBorder(XtDisplay(w), XtWindow(w), + w->core.border_pixel); + } + else { + if (cbw->simple.insensitive_border == None) + cbw->simple.insensitive_border = + XmuCreateStippledPixmap(XtScreen(w), + w->core.border_pixel, + cbw->command.set ? + cbw->label.foreground : + w->core.background_pixel, + w->core.depth); + XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w), + cbw->simple.insensitive_border); + } + } + + return (False); +} diff --git a/src/Converters.c b/src/Converters.c new file mode 100644 index 0000000..9795671 --- /dev/null +++ b/src/Converters.c @@ -0,0 +1,698 @@ +/* + * Copyright (c) 1998 by The XFree86 Project, Inc. + * + * 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 XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#ifndef OLDXAW + +/* + * Definitions + */ +#define done(type, value) \ +{ \ + if (toVal->addr != NULL) \ + { \ + if (toVal->size < sizeof(type)) \ + { \ + toVal->size = sizeof(type); \ + return (False); \ + } \ + *(type *)(toVal->addr) = (value); \ + } \ + else \ + { \ + static type static_val; \ + \ + static_val = (value); \ + toVal->addr = (XPointer)&static_val; \ + } \ + toVal->size = sizeof(type); \ + return (True); \ +} + +#define string_done(value) \ +{ \ + if (toVal->addr != NULL) \ + { \ + if (toVal->size < size) \ + { \ + toVal->size = size; \ + return (False); \ + } \ + strcpy((char *)toVal->addr, (value)); \ + } \ + else \ + toVal->addr = (XPointer)(value); \ + toVal->size = size; \ + return (True); \ +} + +/* + * Prototypes + */ +static Boolean _XawCvtAtomToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtBooleanToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtBoolToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtCARD32ToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtCardinalToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtDimensionToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtDisplayListToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtFontStructToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtIntToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtPixelToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtPixmapToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtShortToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtPositionToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtStringToDisplayList(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtStringToPixmap(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean _XawCvtUnsignedCharToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static void TypeToStringNoArgsWarning(Display*, String); + +/* + * Initialization + */ +static XtConvertArgRec PixelArgs[] = { + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap), + sizeof(Colormap)}, +}; + +static XtConvertArgRec DLArgs[] = { + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen), + sizeof(Screen *)}, + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap), + sizeof(Colormap)}, + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.depth), + sizeof(int)}, +}; +#endif /* OLDXAW */ + +static String XtCToolkitError = "ToolkitError"; +static String XtNconversionError = "conversionError"; + +#ifndef OLDXAW +static String XtNwrongParameters = "wrongParameters"; + +/* + * Implementation + */ +void +XawInitializeDefaultConverters(void) +{ + static Boolean first_time = True; + + if (first_time == False) + return; + + first_time = False; + + /* Replace with more apropriate converters */ + XtSetTypeConverter(XtRCallback, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRColormap, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRFunction, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRPointer, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRScreen, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRStringArray, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRVisual, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRWidget, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRWidgetList, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRWindow, XtRString, _XawCvtCARD32ToString, + NULL, 0, XtCacheNone, NULL); + + XtSetTypeConverter(XtRAtom, XtRString, _XawCvtAtomToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRBool, XtRString, _XawCvtBoolToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRBoolean, XtRString, _XawCvtBooleanToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRCardinal, XtRString, _XawCvtCardinalToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRDimension, XtRString, _XawCvtDimensionToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XawRDisplayList, XtRString, _XawCvtDisplayListToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRFontStruct, XtRString, _XawCvtFontStructToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRInt, XtRString, _XawCvtIntToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRPixel, XtRString, _XawCvtPixelToString, + &PixelArgs[0], XtNumber(PixelArgs), XtCacheNone, NULL); + XtSetTypeConverter(XtRPixmap, XtRString, _XawCvtPixmapToString, + &DLArgs[0], XtNumber(DLArgs), XtCacheNone, NULL); + XtSetTypeConverter(XtRPosition, XtRString, _XawCvtPositionToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRShort, XtRString, _XawCvtShortToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRString, XawRDisplayList, _XawCvtStringToDisplayList, + &DLArgs[0], XtNumber(DLArgs), XtCacheAll, NULL); + XtSetTypeConverter(XtRString, XtRPixmap, _XawCvtStringToPixmap, + &DLArgs[0], XtNumber(DLArgs), XtCacheAll, NULL); + XtSetTypeConverter(XtRUnsignedChar, XtRString, _XawCvtUnsignedCharToString, + NULL, 0, XtCacheNone, NULL); +} +#endif /* OLDXAW */ + +void +XawTypeToStringWarning(Display *dpy, String type) +{ + char fname[64]; + String params[1]; + Cardinal num_params; + + snprintf(fname, sizeof(fname), "cvt%sToString", type); + + params[0] = type; + num_params = 1; + XtAppWarningMsg(XtDisplayToApplicationContext(dpy), + XtNconversionError, fname, XtCToolkitError, + "Cannot convert %s to String", + params, &num_params); +} + +#ifndef OLDXAW +static void +TypeToStringNoArgsWarning(Display *dpy, String type) +{ + char fname[64]; + String params[1]; + Cardinal num_params; + + snprintf(fname, sizeof(fname), "cvt%sToString", type); + + params[0] = type; + num_params = 1; + XtAppWarningMsg(XtDisplayToApplicationContext(dpy), + XtNconversionError, fname, + XtCToolkitError, + "%s to String conversion needs no extra arguments", + params, &num_params); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtBooleanToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[6]; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRBoolean); + + snprintf(buffer, sizeof(buffer), "%s", + *(Boolean *)fromVal->addr ? XtEtrue : XtEfalse); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtBoolToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[6]; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRBool); + + snprintf(buffer, sizeof(buffer), "%s", + *(Bool *)fromVal->addr ? XtEtrue : XtEfalse); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtPositionToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[7]; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRPosition); + + snprintf(buffer, sizeof(buffer), "%d", *(Position *)fromVal->addr); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtShortToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[7]; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRShort); + + snprintf(buffer, sizeof(buffer), "%d", *(short *)fromVal->addr); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtDimensionToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[6]; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRDimension); + + snprintf(buffer, sizeof(buffer), "%u", *(Dimension *)fromVal->addr); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtCARD32ToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[11]; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, "CARD32"); + + snprintf(buffer, sizeof(buffer), "0x%08hx", *(int *)fromVal->addr); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtIntToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[12]; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRInt); + + snprintf(buffer, sizeof(buffer), "%d", *(int *)fromVal->addr); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtCardinalToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[11]; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRCardinal); + + snprintf(buffer, sizeof(buffer), "%u", *(Cardinal *)fromVal->addr); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtAtomToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char *buffer = NULL; + static char *nullatom = "NULL"; + Cardinal size; + Atom atom; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRAtom); + + if (buffer && buffer != nullatom) + XFree(buffer); + + atom = *(Atom *)fromVal[0].addr; + if (atom == 0) + buffer = nullatom; + else if ((buffer = XGetAtomName(dpy, *(Atom *)fromVal[0].addr)) == NULL) + { + XawTypeToStringWarning(dpy, XtRAtom); + toVal->addr = NULL; + toVal->size = sizeof(String); + return (False); + } + + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtPixelToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[19]; + Cardinal size; + Colormap colormap; + XColor color; + + if (*num_args != 1) + { + XtAppWarningMsg(XtDisplayToApplicationContext(dpy), + XtNwrongParameters, "cvtPixelToString", + XtCToolkitError, + "Pixel to String conversion needs colormap argument", + NULL, NULL); + return (False); + } + + colormap = *(Colormap *)args[0].addr; + color.pixel = *(Pixel *)fromVal->addr; + + /* Note: + * If we know the visual type, we can calculate the xcolor + * without asking Xlib. + */ + XQueryColor(dpy, colormap, &color); + snprintf(buffer, sizeof(buffer), "rgb:%04hx/%04hx/%04hx", + color.red, color.green, color.blue); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtFontStructToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[128]; + Cardinal size; + Atom atom; + unsigned long value; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRFontStruct); + + if ((atom = XInternAtom(dpy, "FONT", True)) == None) + return (False); + + size = 0; + + if (XGetFontProperty(*(XFontStruct **)fromVal->addr, atom, &value)) + { + char *tmp = XGetAtomName(dpy, value); + + if (tmp) + { + snprintf(buffer, sizeof(buffer), "%s", tmp); + size = strlen(tmp); + XFree(tmp); + } + } + + if (size) + { + ++size; + string_done(buffer); + } + + XawTypeToStringWarning(dpy, XtRFontStruct); + + return (False); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtUnsignedCharToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char buffer[4]; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XtRUnsignedChar); + + snprintf(buffer, sizeof(buffer), "%u", + *(unsigned char *)fromVal->addr); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtStringToDisplayList(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + XawDisplayList *dlist; + Screen *screen; + Colormap colormap; + int depth; + String commands; + + if (*num_args != 3) + { + XtAppWarningMsg(XtDisplayToApplicationContext(dpy), + XtNwrongParameters, "cvtStringToDisplayList", + XtCToolkitError, + "String to DisplayList conversion needs screen, " + "colormap, and depth arguments", + NULL, NULL); + return (False); + } + + screen = *(Screen **)args[0].addr; + colormap = *(Colormap *)args[1].addr; + depth = *(int *)args[2].addr; + + commands = (String)(fromVal[0].addr); + + dlist = XawCreateDisplayList(commands, screen, colormap, depth); + + if (!dlist) + { + XtDisplayStringConversionWarning(dpy, (String)fromVal->addr, + XawRDisplayList); + toVal->addr = NULL; + toVal->size = sizeof(XawDisplayList*); + return (False); + } + + done(XawDisplayList*, dlist); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtDisplayListToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + String buffer; + Cardinal size; + + if (*num_args != 0) + TypeToStringNoArgsWarning(dpy, XawRDisplayList); + + buffer = XawDisplayListString(*(XawDisplayList **)(fromVal[0].addr)); + size = strlen(buffer) + 1; + + string_done(buffer); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtStringToPixmap(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + XawPixmap *xaw_pixmap; + Pixmap pixmap; + Screen *screen; + Colormap colormap; + int depth; + String name; + + if (*num_args != 3) + { + XtAppWarningMsg(XtDisplayToApplicationContext(dpy), + XtNwrongParameters, "cvtStringToPixmap", + XtCToolkitError, + "String to Pixmap conversion needs screen, " + "colormap, and depth arguments", + NULL, NULL); + return (False); + } + + screen = *(Screen **)args[0].addr; + colormap = *(Colormap *)args[1].addr; + depth = *(int *)args[2].addr; + + name = (String)(fromVal[0].addr); + + if (XmuCompareISOLatin1(name, "None") == 0) + pixmap = None; + else if (XmuCompareISOLatin1(name, "ParentRelative") == 0) + pixmap = ParentRelative; + else if (XmuCompareISOLatin1(name, "XtUnspecifiedPixmap") == 0) + pixmap = XtUnspecifiedPixmap; + else + { + xaw_pixmap = XawLoadPixmap(name, screen, colormap, depth); + if (!xaw_pixmap) + { + XtDisplayStringConversionWarning(dpy, (String)fromVal->addr, + XtRPixmap); + toVal->addr = (XtPointer)XtUnspecifiedPixmap; + toVal->size = sizeof(Pixmap); + return (False); + } + else + pixmap = xaw_pixmap->pixmap; + } + + done(Pixmap, pixmap); +} + +/*ARGSUSED*/ +static Boolean +_XawCvtPixmapToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + XawPixmap *xaw_pixmap; + Pixmap pixmap; + Screen *screen; + Colormap colormap; + int depth; + String buffer = NULL; + Cardinal size; + + if (*num_args != 3) + { + XtAppWarningMsg(XtDisplayToApplicationContext(dpy), + XtNwrongParameters, "cvtPixmapToString", + XtCToolkitError, + "Pixmap to String conversion needs screen, " + "colormap, and depth arguments", + NULL, NULL); + return (False); + } + + screen = *(Screen **)args[0].addr; + colormap = *(Colormap *)args[1].addr; + depth = *(int *)args[2].addr; + + pixmap = *(Pixmap *)(fromVal[0].addr); + + switch (pixmap) + { + case None: + buffer = "None"; + break; + case ParentRelative: + buffer = "ParentRelative"; + break; + case XtUnspecifiedPixmap: + buffer = "XtUnspecifiedPixmap"; + break; + default: + xaw_pixmap = XawPixmapFromXPixmap(pixmap, screen, colormap, depth); + if (xaw_pixmap) + buffer = xaw_pixmap->name; + break; + } + + if (!buffer) + /* Bad Pixmap or Pixmap was not loaded by XawLoadPixmap() */ + return (_XawCvtCARD32ToString(dpy, args, num_args, fromVal, toVal, + converter_data)); + + size = strlen(buffer) + 1; + + string_done(buffer); +} + +#endif /* OLDXAW */ diff --git a/src/Dialog.c b/src/Dialog.c new file mode 100644 index 0000000..9c98d36 --- /dev/null +++ b/src/Dialog.c @@ -0,0 +1,460 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +/* + * After we have set the string in the value widget we set the + * string to a magic value. So that when a SetValues request is made + * on the dialog value we will notice it, and reset the string + */ +#define MAGIC_VALUE ((char *)3) + +#define streq(a,b) (strcmp((a), (b)) == 0) + +/* + * Class Methods + */ +static void XawDialogConstraintInitialize(Widget, Widget, + ArgList, Cardinal*); +static void XawDialogGetValuesHook(Widget, ArgList, Cardinal*); +static void XawDialogInitialize(Widget, Widget, ArgList, Cardinal*); +static Boolean XawDialogSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * Prototypes + */ +static void CreateDialogValueWidget(Widget); + +/* + * Initialization + */ +static XtResource resources[] = { + { + XtNlabel, + XtCLabel, + XtRString, + sizeof(String), + XtOffsetOf(DialogRec, dialog.label), + XtRString, + NULL + }, + { + XtNvalue, + XtCValue, + XtRString, + sizeof(String), + XtOffsetOf(DialogRec, dialog.value), + XtRString, + NULL + }, + { + XtNicon, + XtCIcon, + XtRBitmap, + sizeof(Pixmap), + XtOffsetOf(DialogRec, dialog.icon), + XtRImmediate, + NULL + }, +}; + +DialogClassRec dialogClassRec = { + /* core */ + { + (WidgetClass)&formClassRec, /* superclass */ + "Dialog", /* class_name */ + sizeof(DialogRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + NULL, /* class_part init */ + False, /* class_inited */ + XawDialogInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + XtInheritResize, /* resize */ + XtInheritExpose, /* expose */ + XawDialogSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + XawDialogGetValuesHook, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* composite */ + { + XtInheritGeometryManager, /* geometry_manager */ + XtInheritChangeManaged, /* change_managed */ + XtInheritInsertChild, /* insert_child */ + XtInheritDeleteChild, /* delete_child */ + NULL, /* extension */ + }, + /* constraint */ + { + NULL, /* subresourses */ + 0, /* subresource_count */ + sizeof(DialogConstraintsRec), /* constraint_size */ + XawDialogConstraintInitialize, /* initialize */ + NULL, /* destroy */ + NULL, /* set_values */ + NULL, /* extension */ + }, + /* form */ + { + XtInheritLayout, /* layout */ + }, + /* dialog */ + { + NULL, /* extension */ + } +}; + +WidgetClass dialogWidgetClass = (WidgetClass)&dialogClassRec; + +/* + * Implementation + */ +/*ARGSUSED*/ +static void +XawDialogInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + DialogWidget dw = (DialogWidget)cnew; + Arg arglist[9]; + Cardinal arg_cnt = 0; + + XtSetArg(arglist[arg_cnt], XtNborderWidth, 0); arg_cnt++; + XtSetArg(arglist[arg_cnt], XtNleft, XtChainLeft); arg_cnt++; + + if (dw->dialog.icon != (Pixmap)0) { + XtSetArg(arglist[arg_cnt], XtNbitmap, dw->dialog.icon); arg_cnt++; + XtSetArg(arglist[arg_cnt], XtNright, XtChainLeft); arg_cnt++; + dw->dialog.iconW = XtCreateManagedWidget("icon", labelWidgetClass, + cnew, arglist, arg_cnt); + arg_cnt = 2; + XtSetArg(arglist[arg_cnt], XtNfromHoriz, dw->dialog.iconW); arg_cnt++; + } + else + dw->dialog.iconW = NULL; + + XtSetArg(arglist[arg_cnt], XtNlabel, dw->dialog.label); arg_cnt++; + XtSetArg(arglist[arg_cnt], XtNright, XtChainRight); arg_cnt++; + + dw->dialog.labelW = XtCreateManagedWidget("label", labelWidgetClass, + cnew, arglist, arg_cnt); + + if (dw->dialog.iconW != NULL && + XtHeight(dw->dialog.labelW) < XtHeight(dw->dialog.iconW)) { + XtSetArg(arglist[0], XtNheight, XtHeight(dw->dialog.iconW)); + XtSetValues(dw->dialog.labelW, arglist, 1); + } + if (dw->dialog.value != NULL) + CreateDialogValueWidget((Widget)dw); + else + dw->dialog.valueW = NULL; +} + +/*ARGSUSED*/ +static void +XawDialogConstraintInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + DialogWidget dw = (DialogWidget)cnew->core.parent; + DialogConstraints constraint = (DialogConstraints)cnew->core.constraints; + + if (!XtIsSubclass(cnew, commandWidgetClass)) /* if not a button */ + return; /* then just use defaults */ + + constraint->form.left = constraint->form.right = XtChainLeft; + if (dw->dialog.valueW == NULL) + constraint->form.vert_base = dw->dialog.labelW; + else + constraint->form.vert_base = dw->dialog.valueW; + + if (dw->composite.num_children > 1) { + WidgetList children = dw->composite.children; + Widget *childP; + + for (childP = children + dw->composite.num_children - 1; + childP >= children; childP-- ) { + if (*childP == dw->dialog.labelW || *childP == dw->dialog.valueW) + break; + if (XtIsManaged(*childP) && + XtIsSubclass(*childP, commandWidgetClass)) { + constraint->form.horiz_base = *childP; + break; + } + } + } +} + +#define ICON 0 +#define LABEL 1 +#define NUM_CHECKS 2 +/*ARGSUSED*/ +static Boolean +XawDialogSetValues(Widget current, Widget request, Widget cnew, + ArgList in_args, Cardinal *in_num_args) +{ + DialogWidget w = (DialogWidget)cnew; + DialogWidget old = (DialogWidget)current; + Arg args[5]; + Cardinal num_args; + unsigned int i; + Bool checks[NUM_CHECKS]; + + for (i = 0; i < NUM_CHECKS; i++) + checks[i] = False; + + for (i = 0; i < *in_num_args; i++) { + if (streq(XtNicon, in_args[i].name)) + checks[ICON] = True; + else if (streq(XtNlabel, in_args[i].name)) + checks[LABEL] = True; + } + + if (checks[ICON]) { + if (w->dialog.icon != 0) { + XtSetArg(args[0], XtNbitmap, w->dialog.icon); + if (old->dialog.iconW != NULL) + XtSetValues(old->dialog.iconW, args, 1); + else { + XtSetArg(args[1], XtNborderWidth, 0); + XtSetArg(args[2], XtNleft, XtChainLeft); + XtSetArg(args[3], XtNright, XtChainLeft); + w->dialog.iconW = XtCreateWidget("icon", labelWidgetClass, + cnew, args, 4); + ((DialogConstraints)w->dialog.labelW->core.constraints)-> + form.horiz_base = w->dialog.iconW; + XtManageChild(w->dialog.iconW); + } + } + else if (old->dialog.icon != 0) { + ((DialogConstraints)w->dialog.labelW->core.constraints)-> + form.horiz_base = NULL; + XtDestroyWidget(old->dialog.iconW); + w->dialog.iconW = NULL; + } + } + + if (checks[LABEL]) { + num_args = 0; + XtSetArg(args[num_args], XtNlabel, w->dialog.label); num_args++; + if (w->dialog.iconW != NULL && + XtHeight(w->dialog.labelW) <= XtHeight(w->dialog.iconW)) { + XtSetArg(args[num_args], XtNheight, XtHeight(w->dialog.iconW)); + num_args++; + } + XtSetValues(w->dialog.labelW, args, num_args); + } + + if (w->dialog.value != old->dialog.value) { + if (w->dialog.value == NULL) /* only get here if it + wasn't NULL before */ + XtDestroyWidget(old->dialog.valueW); + else if (old->dialog.value == NULL) { /* create a new value widget */ + XtWidth(w) = XtWidth(old); + XtHeight(w) = XtHeight(old); + CreateDialogValueWidget(cnew); + } + else { /* Widget ok, just change string */ + Arg nargs[1]; + + XtSetArg(nargs[0], XtNstring, w->dialog.value); + XtSetValues(w->dialog.valueW, nargs, 1); + w->dialog.value = MAGIC_VALUE; + } + } + + return (False); +} + +/* + * Function: + * XawDialogGetValuesHook + * + * Parameters: + * w - Dialog Widget + * args - argument list + * num_args - number of args + * + * Description: + * This is a get values hook routine that gets the values in the dialog. + */ +static void +XawDialogGetValuesHook(Widget w, ArgList args, Cardinal *num_args) +{ + Arg a[1]; + String s; + DialogWidget src = (DialogWidget)w; + unsigned int i; + + for (i = 0; i < *num_args; i++) + if (streq(args[i].name, XtNvalue)) { + XtSetArg(a[0], XtNstring, &s); + XtGetValues(src->dialog.valueW, a, 1); + *((char **)args[i].value) = s; + } + else if (streq(args[i].name, XtNlabel)) { + XtSetArg(a[0], XtNlabel, &s); + XtGetValues(src->dialog.labelW, a, 1); + *((char **)args[i].value) = s; + } +} + +/* + * Function: + * CreateDialogValueWidget + * + * Parameters: + * w - dialog widget + * + * Description: + * Creates the dialog widgets value widget. + * + * Note + * Must be called only when w->dialog.value is non-nil + */ +static void +CreateDialogValueWidget(Widget w) +{ + DialogWidget dw = (DialogWidget)w; + Arg arglist[10]; + Cardinal num_args = 0; + + XtSetArg(arglist[num_args], XtNstring, dw->dialog.value); num_args++; + XtSetArg(arglist[num_args], XtNresizable, True); num_args++; + XtSetArg(arglist[num_args], XtNeditType, XawtextEdit); num_args++; + XtSetArg(arglist[num_args], XtNfromVert, dw->dialog.labelW); num_args++; + XtSetArg(arglist[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(arglist[num_args], XtNright, XtChainRight); num_args++; + + dw->dialog.valueW = XtCreateWidget("value", asciiTextWidgetClass, + w, arglist, num_args); + + /* if the value widget is being added after buttons, + * then the buttons need new layout constraints + */ + if (dw->composite.num_children > 1) { + WidgetList children = dw->composite.children; + Widget *childP; + + for (childP = children + dw->composite.num_children - 1; + childP >= children; childP-- ) { + if (*childP == dw->dialog.labelW || *childP == dw->dialog.valueW) + continue; + + if (XtIsManaged(*childP) && + XtIsSubclass(*childP, commandWidgetClass)) { + ((DialogConstraints)(*childP)->core.constraints)-> + form.vert_base = dw->dialog.valueW; + } + } + } + XtManageChild(dw->dialog.valueW); + + /* + * Value widget gets the keyboard focus + */ + XtSetKeyboardFocus(w, dw->dialog.valueW); + dw->dialog.value = MAGIC_VALUE; +} + +void +XawDialogAddButton(Widget dialog, _Xconst char* name, XtCallbackProc function, + XtPointer param) +{ + /* + * Correct Constraints are all set in ConstraintInitialize() + */ + Widget button; + + button = XtCreateManagedWidget(name, commandWidgetClass, dialog, NULL, 0); + + if (function != NULL) /* don't add NULL callback func */ + XtAddCallback(button, XtNcallback, function, param); +} + +char * +XawDialogGetValueString(Widget w) +{ + Arg args[1]; + char *value; + + XtSetArg(args[0], XtNstring, &value); + XtGetValues(((DialogWidget)w)->dialog.valueW, args, 1); + + return(value); +} diff --git a/src/DisplayList.c b/src/DisplayList.c new file mode 100644 index 0000000..4ef89aa --- /dev/null +++ b/src/DisplayList.c @@ -0,0 +1,2255 @@ +/* + * Copyright (c) 1998 by The XFree86 Project, Inc. + * + * 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 XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + * + * Author: Paulo César Pereira de Andrade + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#ifdef __UNIXOS2__ +static char dummy; +#endif + +#ifndef OLDXAW + +/* + * Types + */ +typedef struct _XawDLProc XawDLProc; +typedef struct _XawDLData XawDLData; +typedef struct _XawDLInfo XawDLInfo; + +struct _XawDLProc { + XrmQuark qname; + String *params; + Cardinal num_params; + XawDisplayListProc proc; + XtPointer args; + XawDLData *data; +}; + +struct _XawDLData { + XawDLClass *dlclass; + XtPointer data; +}; + +struct _XawDLInfo { + String name; + XrmQuark qname; + XawDisplayListProc proc; +}; + +struct _XawDL { + XawDLProc **procs; + Cardinal num_procs; + XawDLData **data; + Cardinal num_data; + Screen *screen; + Colormap colormap; + int depth; + XrmQuark qrep; /* for cache lookup */ +}; + +struct _XawDLClass { + String name; + XawDLInfo **infos; + Cardinal num_infos; + XawDLArgsInitProc args_init; + XawDLArgsDestructor args_destructor; + XawDLDataInitProc data_init; + XawDLDataDestructor data_destructor; +}; + +/* + * Private Methods + */ +static XawDLClass *_XawFindDLClass(String); +static int qcmp_dlist_class(_Xconst void*, _Xconst void*); +static int bcmp_dlist_class(_Xconst void*, _Xconst void*); +static XawDLInfo *_XawFindDLInfo(XawDLClass*, String); +static int qcmp_dlist_info(_Xconst void*, _Xconst void*); +static int bcmp_dlist_info(_Xconst void*, _Xconst void*); +static void *_Xaw_Xlib_ArgsInitProc(String, String*, Cardinal*, + Screen*, Colormap, int); +static void _Xaw_Xlib_ArgsDestructor(Display*, String, XtPointer, + String*, Cardinal*); +static void *_Xaw_Xlib_DataInitProc(String, Screen*, Colormap, int); +static void _Xaw_Xlib_DataDestructor(Display*, String, XtPointer); + +/* + * Initialization + */ +static XawDLClass **classes; +static Cardinal num_classes; +static String xlib = "xlib"; + +/* + * Implementation + */ +void +XawRunDisplayList(Widget w, _XawDisplayList *list, + XEvent *event, Region region) +{ + XawDLProc *proc; + Cardinal i; + + if (!XtIsRealized(w)) + return; + + for (i = 0; i < list->num_procs; i++) + { + proc = list->procs[i]; + proc->proc(w, proc->args, proc->data->data, event, region); + } +} + +#define DLERR -2 +#define DLEOF -1 +#define DLEND 1 +#define DLNAME 2 +#define DLARG 3 +static char * +read_token(char *src, char *dst, Cardinal size, int *status) +{ + int ch; + Bool esc, quote; + Cardinal i; + + i = 0; + esc = quote = False; + + /*CONSTCOND*/ + while (1) + { + ch = *src; + if (ch != '\n' && isspace(ch)) + ++src; + else + break; + } + + for (; i < size - 1; src++) + { + ch = *src; + if (ch == '"') + { + if (quote) + { + quote = False; + continue; + } + quote = True; + continue; + } + if (ch == '\\') + { + if (esc) + { + dst[i++] = ch; + esc = False; + continue; + } + esc = True; + continue; + } + if (ch == '\0') + { + *status = DLEOF; + dst[i] = '\0'; + return (src); + } + else if (!esc) + { + if (!quote) + { + if (ch == ',') + { + *status = DLARG; + dst[i] = '\0'; + return (++src); + } + else if (ch == ' ' || ch == '\t') + { + *status = DLNAME; + dst[i] = '\0'; + return (++src); + } + else if (ch == ';' || ch == '\n') + { + *status = DLEND; + dst[i] = '\0'; + return (++src); + } + } + } + else + esc = False; + dst[i++] = ch; + } + + *status = DLERR; + dst[i] = '\0'; + + return (src); +} + +_XawDisplayList *XawCreateDisplayList(String string, Screen *screen, + Colormap colormap, int depth) +{ + _XawDisplayList *dlist; + XawDLClass *lc, *xlibc; + XawDLData *data; + XawDLInfo *info; + XawDLProc *proc; + char cname[64], fname[64], aname[1024]; + Cardinal i; + char *cp, *fp, *lp; + int status; + + xlibc = XawGetDisplayListClass(xlib); + if (!xlibc) + { + XawDisplayListInitialize(); + xlibc = XawGetDisplayListClass(xlib); + } + + dlist = (_XawDisplayList *)XtMalloc(sizeof(_XawDisplayList)); + dlist->procs = NULL; + dlist->num_procs = 0; + dlist->data = NULL; + dlist->num_data = 0; + dlist->screen = screen; + dlist->colormap = colormap; + dlist->depth = depth; + dlist->qrep = NULLQUARK; + if (!string || !string[0]) + return (dlist); + + cp = string; + + status = 0; + while (status != DLEOF) + { + lp = cp; + cp = read_token(cp, fname, sizeof(fname), &status); + + if (status != DLNAME && status != DLEND && status != DLEOF) + { + char msg[256]; + + snprintf(msg, sizeof(msg), + "Error parsing displayList at \"%s\"", lp); + XtAppWarning(XtDisplayToApplicationContext(DisplayOfScreen(screen)), + msg); + XawDestroyDisplayList(dlist); + return (NULL); + } + fp = fname; + /*CONSTCOND*/ + while (1) + { + fp = strchr(fp, ':'); + if (!fp || (fp == cp || fp[-1] != '\\')) + break; + ++fp; + } + if (fp) + { + snprintf(cname, fp - fname + 1, fname); + memmove(fname, fp + 1, strlen(fp)); + lc = cname[0] ? XawGetDisplayListClass(cname) : xlibc; + if (!lc) + { + char msg[256]; + + snprintf(msg, sizeof(msg), + "Cannot find displayList class \"%s\"", cname); + XtAppWarning(XtDisplayToApplicationContext + (DisplayOfScreen(screen)), msg); + XawDestroyDisplayList(dlist); + return (NULL); + } + } + else + lc = xlibc; + + if (status == DLEOF && !fname[0]) + break; + + if ((info = _XawFindDLInfo(lc, fname)) == NULL) + { + char msg[256]; + + snprintf(msg, sizeof(msg), + "Cannot find displayList procedure \"%s\"", fname); + XtAppWarning(XtDisplayToApplicationContext(DisplayOfScreen(screen)), + msg); + XawDestroyDisplayList(dlist); + return (NULL); + } + + proc = (XawDLProc *)XtMalloc(sizeof(XawDLProc)); + proc->qname = info->qname; + proc->params = NULL; + proc->num_params = 0; + proc->proc = info->proc; + proc->args = NULL; + proc->data = NULL; + + if (!dlist->procs) + { + dlist->num_procs = 1; + dlist->procs = (XawDLProc**)XtMalloc(sizeof(XawDLProc*)); + } + else + { + ++dlist->num_procs; + dlist->procs = (XawDLProc**) + XtRealloc((char *)dlist->procs, sizeof(XawDLProc*) * + dlist->num_procs); + } + dlist->procs[dlist->num_procs - 1] = proc; + + while (status != DLEND && status != DLEOF) + { + lp = cp; + cp = read_token(cp, aname, sizeof(aname), &status); + + if (status != DLARG && status != DLEND && status != DLEOF) + { + char msg[256]; + + snprintf(msg, sizeof(msg), + "Error parsing displayList at \"%s\"", lp); + XtAppWarning(XtDisplayToApplicationContext + (DisplayOfScreen(screen)), msg); + XawDestroyDisplayList(dlist); + return (NULL); + } + + if (!proc->num_params) + { + proc->num_params = 1; + proc->params = (String *)XtMalloc(sizeof(String)); + } + else + { + ++proc->num_params; + proc->params = (String *)XtRealloc((char *)proc->params, + sizeof(String) * + proc->num_params); + } + proc->params[proc->num_params - 1] = XtNewString(aname); + } + + /* verify if data is already created for lc */ + data = NULL; + for (i = 0; i < dlist->num_data; i++) + if (dlist->data[i]->dlclass == lc) + { + data = dlist->data[i]; + break; + } + + if (!data) + { + data = (XawDLData *)XtMalloc(sizeof(XawDLData)); + data->dlclass = lc; + if (lc->data_init) + data->data = lc->data_init(lc->name, screen, colormap, depth); + else + data->data = NULL; + + if (!dlist->data) + { + dlist->num_data = 1; + dlist->data = (XawDLData **)XtMalloc(sizeof(XawDLData*)); + } + else + { + ++dlist->num_data; + dlist->data = (XawDLData **) + XtRealloc((char *)dlist->data, sizeof(XawDLData*) * + dlist->num_data); + } + dlist->data[dlist->num_data - 1] = data; + } + + if (lc->args_init) + { + proc->args = lc->args_init(fname, proc->params, &proc->num_params, + screen, colormap, depth); + if (proc->args == XAWDL_CONVERT_ERROR) + { + char msg[256]; + + proc->args = NULL; + snprintf(msg, sizeof(msg), + "Cannot convert arguments to displayList function \"%s\"", + fname); + XtAppWarning(XtDisplayToApplicationContext + (DisplayOfScreen(screen)), msg); + XawDestroyDisplayList(dlist); + return (NULL); + } + } + else + proc->args = NULL; + + proc->data = data; + } + + dlist->qrep = XrmStringToQuark(string); + return (dlist); +} + +String +XawDisplayListString(_XawDisplayList *dlist) +{ + if (!dlist || dlist->qrep == NULLQUARK) + return (""); + return (XrmQuarkToString(dlist->qrep)); +} + +void +XawDestroyDisplayList(_XawDisplayList *dlist) +{ + Cardinal i, j; + XawDLProc *proc; + XawDLData *data; + + if (!dlist) + return; + + for (i = 0; i < dlist->num_procs; i++) + { + proc = dlist->procs[i]; + data = proc->data; + + if (data) + { + if (data->dlclass->args_destructor) + data->dlclass->args_destructor(DisplayOfScreen(dlist->screen), + XrmQuarkToString(proc->qname), + proc->args, + proc->params, &proc->num_params); + if (data->data) + { + if (data->dlclass->data_destructor) + { + data->dlclass + ->data_destructor(DisplayOfScreen(dlist->screen), + data->dlclass->name, data->data); + data->data = NULL; + } + } + } + + for (j = 0; j < proc->num_params; j++) + XtFree(proc->params[j]); + if (proc->num_params) + XtFree((char *)proc->params); + XtFree((char *)proc); + } + + if (dlist->num_procs) + XtFree((char *)dlist->procs); + + XtFree((char *)dlist); +} + +/********************************************************************** + * If you want to implement your own class of procedures, look at + * the code bellow. + **********************************************************************/ +/* Start of Implementation of class "xlib" */ +typedef struct _XawXlibData { + GC gc; + unsigned long mask; + XGCValues values; + int shape; + int mode; + char *dashes; + /* these fields can be used for optimization, to + * avoid unnecessary coordinates recalculation. + */ + Position x, y; + Dimension width, height; +} XawXlibData; + +typedef struct _XawDLPosition { + Position pos; + short denom; + Boolean high; +} XawDLPosition; + +typedef struct _XawDLPositionPtr { + XawDLPosition *pos; + Cardinal num_pos; +} XawDLPositionPtr; + +typedef struct _XawDLArcArgs { + XawDLPosition pos[4]; + int angle1; + int angle2; +} XawDLArcArgs; + +typedef struct _XawDLStringArgs { + XawDLPosition pos[2]; + char *string; + int length; +} XawDLStringArgs; + +typedef struct _XawDLCopyArgs { + XawPixmap *pixmap; + XawDLPosition pos[6]; + int plane; +} XawDLCopyArgs; + +typedef struct _XawDLImageArgs { + XawPixmap *pixmap; + XawDLPosition pos[4]; + int depth; +} XawDLImageArgs; + +#define X_ARG(x) (Position)(((x).denom != 0) ? \ + ((float)XtWidth(w) * ((float)(x).pos / (float)(x).denom)) : \ + ((x).high ? XtWidth(w) - (x).pos : (x).pos)) +#define Y_ARG(x) (Position)(((x).denom != 0) ? \ + ((float)XtHeight(w) * ((float)(x).pos / (float)(x).denom)): \ + ((x).high ? XtHeight(w) - (x).pos : (x).pos)) +#define DRECT 0 +#define FRECT 1 +#define LINE 2 +#define GCFG 3 +#define GCBG 4 +#define FPOLY 5 +#define DARC 6 +#define FARC 7 +#define DLINES 8 +#define MASK 9 +#define UMASK 10 +#define LWIDTH 11 +#define POINT 12 +#define POINTS 13 +#define SEGMENTS 14 +#define ARCMODE 15 +#define COORDMODE 16 +#define SHAPEMODE 17 +#define LINESTYLE 18 +#define CAPSTYLE 19 +#define JOINSTYLE 20 +#define FILLSTYLE 21 +#define FILLRULE 22 +#define TILE 23 +#define STIPPLE 24 +#define TSORIGIN 25 +#define FUNCTION 26 +#define PLANEMASK 27 +#define DSTRING 28 +#define PSTRING 29 +#define FONT 30 +#define DASHES 31 +#define SUBWMODE 32 +#define EXPOSURES 33 +#define CLIPORIGIN 34 +#define CLIPMASK 35 +#define CLIPRECTS 36 +#define COPYAREA 37 +#define COPYPLANE 38 +#define IMAGE 39 + +static void +Dl1Point(Widget w, XtPointer args, XtPointer data, int id) +{ + XawDLPosition *pos = (XawDLPosition *)args; + XawXlibData *xdata = (XawXlibData *)data; + Display *display; + Window window; + Position x, y; + + x = X_ARG(pos[0]); + y = Y_ARG(pos[1]); + + if (!XtIsWidget(w)) + { + Position xpad, ypad; + + xpad = XtX(w) + XtBorderWidth(w); + ypad = XtY(w) + XtBorderWidth(w); + x += xpad; + y += ypad; + display = XtDisplayOfObject(w); + window = XtWindowOfObject(w); + } + else + { + display = XtDisplay(w); + window = XtWindow(w); + } + + if (id == POINT) + XDrawPoint(display, window, xdata->gc, x, y); + else if (id == TSORIGIN) + { + xdata->values.ts_x_origin = x; + xdata->values.ts_y_origin = y; + xdata->mask |= GCTileStipXOrigin | GCTileStipYOrigin; + XSetTSOrigin(display, xdata->gc, x, y); + } + else if (id == CLIPORIGIN) + { + xdata->values.clip_x_origin = x; + xdata->values.clip_y_origin = y; + xdata->mask |= GCClipXOrigin | GCClipYOrigin; + XSetClipOrigin(display, xdata->gc, x, y); + } +} + +static void +Dl2Points(Widget w, XtPointer args, XtPointer data, int id) +{ + XawDLPosition *pos = (XawDLPosition *)args; + XawXlibData *xdata = (XawXlibData *)data; + Display *display; + Window window; + Position x1, y1, x2, y2; + + x1 = X_ARG(pos[0]); + y1 = Y_ARG(pos[1]); + x2 = X_ARG(pos[2]); + y2 = Y_ARG(pos[3]); + + if (!XtIsWidget(w)) + { + Position xpad, ypad; + + xpad = XtX(w) + XtBorderWidth(w); + ypad = XtY(w) + XtBorderWidth(w); + x1 += xpad; y1 += ypad; + x2 += xpad; y2 += ypad; + display = XtDisplayOfObject(w); + window = XtWindowOfObject(w); + } + else + { + display = XtDisplay(w); + window = XtWindow(w); + } + + if (id == DRECT) + XDrawRectangle(display, window, xdata->gc, x1, y1, x2 - x1, y2 - y1); + else if (id == FRECT) + XFillRectangle(display, window, xdata->gc, x1, y1, x2 - x1, y2 - y1); + else if (id == LINE) + XDrawLine(display, window, xdata->gc, x1, y1, x2, y2); +} + +/* ARGSUSED */ +static void +DlLine(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region) +{ + Dl2Points(w, args, data, LINE); +} + +/* ARGSUSED */ +static void +DlDrawRectangle(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + Dl2Points(w, args, data, DRECT); +} + +/* ARGSUSED */ +static void +DlFillRectangle(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + Dl2Points(w, args, data, FRECT); +} + +static void +DlXPoints(Widget w, XtPointer args, XtPointer data, int id) +{ + XawDLPositionPtr *pos_ptr = (XawDLPositionPtr *)args; + XawXlibData *xdata = (XawXlibData *)data; + XawDLPosition *pos; + XPoint points_buf[16]; + XPoint *points; + Display *display; + Window window; + Cardinal num_points, i, j; + + num_points = pos_ptr->num_pos>>1; + points = (XPoint *)XawStackAlloc(sizeof(XPoint) * num_points, points_buf); + + for (i = j = 0; i < num_points; i++, j = i << 1) + { + pos = &pos_ptr->pos[j]; + points[i].x = X_ARG(pos[0]); + points[i].y = Y_ARG(pos[1]); + } + + if (!XtIsWidget(w)) + { + Position xpad, ypad; + + xpad = XtX(w) + XtBorderWidth(w); + ypad = XtY(w) + XtBorderWidth(w); + if (xdata->mode != CoordModePrevious) + { + for (i = 0; i < num_points; i++) + { + points[i].x += xpad; + points[i].y += ypad; + } + } + else + { + points[0].x += xpad; + points[0].y += ypad; + } + display = XtDisplayOfObject(w); + window = XtWindowOfObject(w); + } + else + { + display = XtDisplay(w); + window = XtWindow(w); + } + + if (id == FPOLY) + XFillPolygon(display, window, xdata->gc, points, num_points, + xdata->shape, xdata->mode); + else if (id == DLINES) + XDrawLines(display, window, xdata->gc, points, num_points, xdata->mode); + else if (id == POINTS) + XDrawPoints(display, window, xdata->gc, points, num_points, xdata->mode); + + XawStackFree(points, points_buf); +} + +/* ARGSUSED */ +static void +DlFillPolygon(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + DlXPoints(w, args, data, FPOLY); +} + +/* ARGSUSED */ +static void +DlDrawLines(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + DlXPoints(w, args, data, DLINES); +} + +/* ARGSUSED */ +static void +DlDrawPoints(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + DlXPoints(w, args, data, POINTS); +} + +/* ARGSUSED */ +static void +DlForeground(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + Pixel foreground = (Pixel)args; + + if (xdata->values.foreground != foreground) + { + xdata->mask |= GCForeground; + xdata->values.foreground = foreground; + XSetForeground(XtDisplayOfObject(w), xdata->gc, foreground); + } +} + +/* ARGSUSED */ +static void +DlBackground(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + Pixel background = (Pixel)args; + + if (xdata->values.background != background) + { + xdata->mask |= GCBackground; + xdata->values.background = background; + XSetBackground(XtDisplayOfObject(w), xdata->gc, background); + } +} + +static void +DlArc(Widget w, XtPointer args, XtPointer data, Bool fill) +{ + XawXlibData *xdata = (XawXlibData *)data; + XawDLArcArgs *arc = (XawDLArcArgs *)args; + Position x1, y1, x2, y2; + Display *display; + Window window; + + x1 = X_ARG(arc->pos[0]); + y1 = Y_ARG(arc->pos[1]); + x2 = X_ARG(arc->pos[2]); + y2 = Y_ARG(arc->pos[3]); + + if (!XtIsWidget(w)) + { + Position xpad, ypad; + + xpad = XtX(w) + XtBorderWidth(w); + ypad = XtY(w) + XtBorderWidth(w); + x1 += xpad; + y1 += ypad; + x2 += xpad; + y2 += ypad; + display = XtDisplayOfObject(w); + window = XtWindowOfObject(w); + } + else + { + display = XtDisplay(w); + window = XtWindow(w); + } + + if (fill) + XFillArc(display, window, xdata->gc, x1, y1, x2 - x1, y2 - y1, + arc->angle1, arc->angle2); + else + XDrawArc(display, window, xdata->gc, x1, y1, x2 - x1, y2 - y1, + arc->angle1, arc->angle2); +} + +/* ARGSUSED */ +static void +DlDrawArc(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + DlArc(w, args, data, False); +} + +/* ARGSUSED */ +static void +DlFillArc(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + DlArc(w, args, data, True); +} + +/*ARGSUSED*/ +static void +DlMask(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + Display *display = XtDisplayOfObject(w); + + if (region) + XSetRegion(display, xdata->gc, region); + else if (event) + { + XRectangle rect; + + rect.x = event->xexpose.x; + rect.y = event->xexpose.y; + rect.width = event->xexpose.width; + rect.height = event->xexpose.height; + XSetClipRectangles(display, xdata->gc, 0, 0, &rect, 1, Unsorted); + } +} + +/* ARGSUSED */ +static void +DlUmask(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + + XSetClipMask(XtDisplayOfObject(w), xdata->gc, None); +} + +/* ARGSUSED */ +static void +DlLineWidth(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + unsigned line_width = (unsigned long)args; + + if (xdata->values.line_width != line_width) + { + xdata->mask |= GCLineWidth; + xdata->values.line_width = line_width; + XChangeGC(XtDisplayOfObject(w), xdata->gc, GCLineWidth, &xdata->values); + } +} + +/* ARGSUSED */ +static void +DlDrawPoint(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region) +{ + Dl1Point(w, args, data, POINT); +} + +/* ARGSUSED */ +static void +DlDrawSegments(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawDLPositionPtr *pos_ptr = (XawDLPositionPtr *)args; + XawXlibData *xdata = (XawXlibData *)data; + XawDLPosition *pos; + XSegment *segments; + XSegment segments_buf[8]; + Display *display; + Window window; + Cardinal num_segments, i, j; + + num_segments = pos_ptr->num_pos>>2; + segments = (XSegment *)XawStackAlloc(sizeof(XSegment) * num_segments, segments_buf); + + for (i = j = 0; i < num_segments; i++, j = i << 2) + { + pos = &pos_ptr->pos[j]; + segments[i].x1 = X_ARG(pos[0]); + segments[i].y1 = Y_ARG(pos[1]); + segments[i].x2 = X_ARG(pos[2]); + segments[i].y2 = Y_ARG(pos[3]); + } + + if (!XtIsWidget(w)) + { + Position xpad, ypad; + + xpad = XtX(w) + XtBorderWidth(w); + ypad = XtY(w) + XtBorderWidth(w); + for (i = 0; i < num_segments; i++) + { + segments[i].x1 += xpad; + segments[i].y1 += ypad; + segments[i].x2 += xpad; + segments[i].y2 += ypad; + } + display = XtDisplayOfObject(w); + window = XtWindowOfObject(w); + } + else + { + display = XtDisplay(w); + window = XtWindow(w); + } + + XDrawSegments(display, window, xdata->gc, segments, num_segments); + + XawStackFree(segments, segments_buf); +} + +/* ARGSUSED */ +static void +DlArcMode(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int arc_mode = (long)args; + + if (xdata->values.arc_mode != arc_mode) + { + xdata->mask |= GCArcMode; + xdata->values.arc_mode = arc_mode; + XSetArcMode(XtDisplayOfObject(w), xdata->gc, arc_mode); + } +} + +/* ARGSUSED */ +static void +DlCoordMode(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int mode = (long)args; + + xdata->mode = mode; +} + +/* ARGSUSED */ +static void +DlShapeMode(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int shape = (long)args; + + xdata->shape = shape; +} + +/* ARGSUSED */ +static void +DlLineStyle(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int line_style = (long)args; + + if (xdata->values.line_style != line_style) + { + xdata->mask |= GCLineStyle; + xdata->values.line_style = line_style; + XChangeGC(XtDisplayOfObject(w), xdata->gc, GCLineStyle, &xdata->values); + } +} + +/* ARGSUSED */ +static void +DlCapStyle(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int cap_style = (long)args; + + if (xdata->values.cap_style != cap_style) + { + xdata->mask |= GCCapStyle; + xdata->values.cap_style = cap_style; + XChangeGC(XtDisplayOfObject(w), xdata->gc, GCCapStyle, &xdata->values); + } +} + +/* ARGSUSED */ +static void +DlJoinStyle(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int join_style = (long)args; + + if (xdata->values.join_style != join_style) + { + xdata->mask |= GCJoinStyle; + xdata->values.join_style = join_style; + XChangeGC(XtDisplayOfObject(w), xdata->gc, GCJoinStyle, &xdata->values); + } +} + +/* ARGSUSED */ +static void +DlFillStyle(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int fill_style = (long)args; + + if (xdata->values.fill_style != fill_style) + { + xdata->mask |= GCFillStyle; + xdata->values.fill_style = fill_style; + XSetFillStyle(XtDisplayOfObject(w), xdata->gc, fill_style); + } +} + +/* ARGSUSED */ +static void +DlFillRule(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int fill_rule = (long)args; + + if (xdata->values.fill_rule != fill_rule) + { + xdata->mask |= GCFillRule; + xdata->values.fill_rule = fill_rule; + XSetFillRule(XtDisplayOfObject(w), xdata->gc, fill_rule); + } +} + +/* ARGSUSED */ +static void +DlTile(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + XawPixmap *pixmap = (XawPixmap *)args; + + if (pixmap && xdata->values.tile != pixmap->pixmap) + { + xdata->mask |= GCTile; + xdata->values.tile = pixmap->pixmap; + XSetTile(XtDisplayOfObject(w), xdata->gc, xdata->values.tile); + } +} + +/* ARGSUSED */ +static void +DlStipple(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + XawPixmap *pixmap = (XawPixmap *)args; + + if (pixmap && xdata->values.stipple != pixmap->pixmap) + { + xdata->mask |= GCStipple; + xdata->values.stipple = pixmap->pixmap; + XSetStipple(XtDisplayOfObject(w), xdata->gc, xdata->values.stipple); + } +} + +/* ARGSUSED */ +static void +DlTSOrigin(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region) +{ + Dl1Point(w, args, data, TSORIGIN); +} + +/* ARGSUSED */ +static void +DlFunction(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int function = (long)args; + + if (function != xdata->values.function) + { + xdata->mask |= GCFunction; + xdata->values.function = function; + XSetFunction(XtDisplayOfObject(w), xdata->gc, function); + } +} + +/* ARGSUSED */ +static void +DlPlaneMask(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + unsigned long plane_mask = (unsigned long)args; + + if (xdata->values.plane_mask != plane_mask) + { + xdata->mask |= GCPlaneMask; + xdata->values.plane_mask = plane_mask; + XSetPlaneMask(XtDisplayOfObject(w), xdata->gc, plane_mask); + } +} + +static void +DlString(Widget w, XtPointer args, XtPointer data, Bool image) +{ + XawDLStringArgs *string = (XawDLStringArgs *)args; + XawXlibData *xdata = (XawXlibData *)data; + Display *display; + Window window; + Position x, y; + + x = X_ARG(string->pos[0]); + y = Y_ARG(string->pos[1]); + + if (!XtIsWidget(w)) + { + Position xpad, ypad; + + xpad = XtX(w) + XtBorderWidth(w); + ypad = XtY(w) + XtBorderWidth(w); + x += xpad; + y += ypad; + display = XtDisplayOfObject(w); + window = XtWindowOfObject(w); + } + else + { + display = XtDisplay(w); + window = XtWindow(w); + } + + if (image) + XDrawImageString(display, window, xdata->gc, x, y, string->string, string->length); + else + XDrawString(display, window, xdata->gc, x, y, string->string, string->length); +} + +/* ARGSUSED */ +static void +DlDrawString(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + DlString(w, args, data, False); +} + +/* ARGSUSED */ +static void +DlPaintString(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + DlString(w, args, data, True); +} + +/* ARGSUSED */ +static void +DlFont(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + Font font = (Font)args; + + if (xdata->values.font != font) + { + xdata->mask |= GCFont; + xdata->values.font = font; + XSetFont(XtDisplayOfObject(w), xdata->gc, font); + } +} + +/* ARGSUSED */ +static void +DlDashes(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + char *dashes = args; + + if (xdata->dashes != dashes) + { + xdata->mask |= GCDashOffset | GCDashList; + xdata->dashes = dashes; + XSetDashes(XtDisplayOfObject(w), xdata->gc, 0, dashes + 1, *dashes); + } +} + +/* ARGSUSED */ +static void +DlSubwindowMode(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + int subwindow_mode = (long)args; + + if (xdata->values.subwindow_mode != subwindow_mode) + { + xdata->mask |= GCSubwindowMode; + xdata->values.subwindow_mode = subwindow_mode; + XSetSubwindowMode(XtDisplayOfObject(w), xdata->gc, subwindow_mode); + } +} + +/* ARGSUSED */ +static void +DlExposures(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + Bool graphics_exposures = (Bool)(long)args; + + if (xdata->values.graphics_exposures != graphics_exposures) + { + xdata->mask |= GCGraphicsExposures; + xdata->values.graphics_exposures = graphics_exposures; + XSetGraphicsExposures(XtDisplayOfObject(w), xdata->gc, graphics_exposures); + } +} + +/* ARGSUSED */ +static void +DlClipOrigin(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region) +{ + Dl1Point(w, args, data, CLIPORIGIN); +} + +/* ARGSUSED */ +static void +DlClipMask(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawXlibData *xdata = (XawXlibData *)data; + XawPixmap *pixmap = (XawPixmap *)args; + Pixmap clip_mask; + + if (pixmap) + clip_mask = pixmap->mask ? pixmap->mask : pixmap->pixmap; + else + clip_mask = None; + + if (xdata->values.clip_mask != clip_mask) + { + xdata->mask |= GCClipMask; + XSetClipMask(XtDisplayOfObject(w), xdata->gc, clip_mask); + } +} + +/* ARGSUSED */ +static void +DlClipRectangles(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + XawDLPositionPtr *pos_ptr = (XawDLPositionPtr *)args; + XawXlibData *xdata = (XawXlibData *)data; + XawDLPosition *pos; + XRectangle *rects; + XRectangle rects_buf[8]; + Position x1, y1, x2, y2; + Cardinal num_rects, i, j; + + num_rects = pos_ptr->num_pos>>2; + rects = (XRectangle *)XawStackAlloc(sizeof(XRectangle) * num_rects, rects_buf); + + for (i = j = 0; i < num_rects; i++, j = i << 2) + { + pos = &pos_ptr->pos[j]; + x1 = X_ARG(pos[0]); + y1 = Y_ARG(pos[1]); + x2 = X_ARG(pos[2]); + y2 = Y_ARG(pos[3]); + rects[i].x = XawMin(x1, x2); + rects[i].y = XawMin(y1, y2); + rects[i].width = XawMax(x1, x2) - rects[i].x; + rects[i].height = XawMax(y1, y2) - rects[i].y; + } + + if (!XtIsWidget(w)) + { + Position xpad, ypad; + + xpad = XtX(w) + XtBorderWidth(w); + ypad = XtY(w) + XtBorderWidth(w); + for (i = 0; i < num_rects; i++) + { + rects[i].x += xpad; + rects[i].y += ypad; + } + } + + XSetClipRectangles(XtDisplayOfObject(w), xdata->gc, 0, 0, rects, num_rects, Unsorted); + + XawStackFree(rects, rects_buf); +} + +static void +DlCopy(Widget w, XtPointer args, XtPointer data, Bool plane) +{ + XawDLCopyArgs *copy = (XawDLCopyArgs *)args; + XawXlibData *xdata = (XawXlibData *)data; + int src_x, src_y, dst_x, dst_y, width, height, tmp1, tmp2; + + tmp1 = X_ARG(copy->pos[0]); + tmp2 = X_ARG(copy->pos[2]); + dst_x = XawMin(tmp1, tmp2); + width = XawMax(tmp1, tmp2) - dst_x; + + tmp1 = Y_ARG(copy->pos[1]); + tmp2 = Y_ARG(copy->pos[3]); + dst_y = XawMin(tmp1, tmp2); + height = XawMax(tmp1, tmp2) - dst_y; + + src_x = X_ARG(copy->pos[4]); + src_y = Y_ARG(copy->pos[5]); + + if (width <= 0) + { + if (copy->pixmap) + width = copy->pixmap->width; + else + { + if ((width = XtWidth(w) - src_x) < 0) + width = 0; + } + } + if (height <= 0) + { + if (copy->pixmap) + height = copy->pixmap->height; + else + { + if ((height = XtHeight(w) - src_y) < 0) + height = 0; + } + } + + if (!XtIsWidget(w)) + { + Position xpad, ypad; + + xpad = XtX(w) + XtBorderWidth(w); + ypad = XtY(w) + XtBorderWidth(w); + src_x += xpad; + src_y += ypad; + dst_x += xpad; + dst_y += ypad; + } + + if (plane) + XCopyPlane(XtDisplayOfObject(w), XtWindowOfObject(w), + copy->pixmap ? copy->pixmap->pixmap : XtWindowOfObject(w), + xdata->gc, src_x, src_y, width, height, dst_x, dst_y, + copy->plane ? copy->plane : 1); + else + XCopyArea(XtDisplayOfObject(w), + copy->pixmap ? copy->pixmap->pixmap : XtWindowOfObject(w), + XtWindowOfObject(w), xdata->gc, src_x, src_y, width, height, dst_x, dst_y); +} + +/* ARGSUSED */ +static void +DlCopyArea(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + DlCopy(w, args, data, False); +} + +/* ARGSUSED */ +static void +DlCopyPlane(Widget w, XtPointer args, XtPointer data, + XEvent *event, Region region) +{ + DlCopy(w, args, data, True); +} + +/*ARGSUSED*/ +/* Note: + * This function is destructive if you set the ts_x_origin, ts_y_origin, + * and/or clip-mask. It is meant to be the only function used in a display + * list. If you need to use other functions (and those values), be sure to + * set them after calling this function. + */ +static void +DlImage(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region) +{ + XawDLImageArgs *image = (XawDLImageArgs *)args; + XawXlibData *xdata = (XawXlibData *)data; + int x, y, xs, ys, xe, ye, width, height; + Display *display; + Window window; + + width = image->pixmap->width; + height = image->pixmap->height; + xs = X_ARG(image->pos[0]); + ys = Y_ARG(image->pos[1]); + xe = X_ARG(image->pos[2]); + ye = Y_ARG(image->pos[3]); + + if (xe <= 0) + xe = xs + width; + if (ye <= 0) + ye = ys + height; + + if (!XtIsWidget(w)) + { + Position xpad, ypad; + + xpad = XtX(w) + XtBorderWidth(w); + ypad = XtY(w) + XtBorderWidth(w); + xe += xpad; + ye += ypad; + xe += xpad; + ye += ypad; + display = XtDisplayOfObject(w); + window = XtWindowOfObject(w); + } + else + { + display = XtDisplay(w); + window = XtWindow(w); + } + + for (y = ys; y < ye; y += height) + for (x = xs; x < xe; x += width) + { + XSetClipOrigin(display, xdata->gc, x, y); + if (image->pixmap->mask) + XSetClipMask(display, xdata->gc, image->pixmap->mask); + if (image->depth == 1) + XCopyPlane(display, image->pixmap->pixmap, window, xdata->gc, + 0, 0, XawMin(width, xe - x), XawMin(height, ye - y), + x, y, 1L); + else + XCopyArea(display, image->pixmap->pixmap, window, xdata->gc, 0, 0, + XawMin(width, xe - x), XawMin(height, ye - y), x, y); + } + + XSetClipMask(display, xdata->gc, None); +} + +typedef struct _Dl_init Dl_init; +struct _Dl_init { + String name; + XawDisplayListProc proc; + Cardinal id; +}; + +static Dl_init dl_init[] = +{ + {"arc-mode", DlArcMode, ARCMODE}, + {"background", DlBackground, GCBG}, + {"bg", DlBackground, GCBG}, + {"cap-style", DlCapStyle, CAPSTYLE}, + {"clip-mask", DlClipMask, CLIPMASK}, + {"clip-origin", DlClipOrigin, CLIPORIGIN}, + {"clip-rectangles", DlClipRectangles, CLIPRECTS}, + {"clip-rects", DlClipRectangles, CLIPRECTS}, + {"coord-mode", DlCoordMode, COORDMODE}, + {"copy-area", DlCopyArea, COPYAREA}, + {"copy-plane", DlCopyPlane, COPYPLANE}, + {"dashes", DlDashes, DASHES}, + {"draw-arc", DlDrawArc, DARC}, + {"draw-line", DlLine, LINE}, + {"draw-lines", DlDrawLines, DLINES}, + {"draw-point", DlDrawPoint, POINT}, + {"draw-points", DlDrawPoints, POINTS}, + {"draw-rect", DlDrawRectangle, DRECT}, + {"draw-rectangle", DlDrawRectangle, DRECT}, + {"draw-segments", DlDrawSegments, SEGMENTS}, + {"draw-string", DlDrawString, DSTRING}, + {"exposures", DlExposures, EXPOSURES}, + {"fg", DlForeground, GCFG}, + {"fill-arc", DlFillArc, FARC}, + {"fill-poly", DlFillPolygon, FPOLY}, + {"fill-polygon", DlFillPolygon, FPOLY}, + {"fill-rect", DlFillRectangle, FRECT}, + {"fill-rectangle", DlFillRectangle, FRECT}, + {"fill-rule", DlFillRule, FILLRULE}, + {"fill-style", DlFillStyle, FILLSTYLE}, + {"font", DlFont, FONT}, + {"foreground", DlForeground, GCFG}, + {"function", DlFunction, FUNCTION}, + {"image", DlImage, IMAGE}, + {"join-style", DlJoinStyle, JOINSTYLE}, + {"line", DlLine, LINE}, + {"line-style", DlLineStyle, LINESTYLE}, + {"line-width", DlLineWidth, LWIDTH}, + {"lines", DlDrawLines, DLINES}, + {"mask", DlMask, MASK}, + {"paint-string", DlPaintString, PSTRING}, + {"plane-mask", DlPlaneMask, PLANEMASK}, + {"point", DlDrawPoint, POINT}, + {"points", DlDrawPoints, POINTS}, + {"segments", DlDrawSegments, SEGMENTS}, + {"shape-mode", DlShapeMode, SHAPEMODE}, + {"stipple", DlStipple, STIPPLE}, + {"subwindow-mode", DlSubwindowMode, SUBWMODE}, + {"tile", DlTile, TILE}, + {"ts-origin", DlTSOrigin, TSORIGIN}, + {"umask", DlUmask, UMASK}, +}; + +void +XawDisplayListInitialize(void) +{ + static Bool first_time = True; + XawDLClass *lc; + Cardinal i; + + if (first_time == False) + return; + + first_time = False; + + lc = XawCreateDisplayListClass(xlib, + _Xaw_Xlib_ArgsInitProc, + _Xaw_Xlib_ArgsDestructor, + _Xaw_Xlib_DataInitProc, + _Xaw_Xlib_DataDestructor); + for (i = 0; i < sizeof(dl_init) / sizeof(dl_init[0]); i++) + (void)XawDeclareDisplayListProc(lc, dl_init[i].name, dl_init[i].proc); +} + +static int +bcmp_cvt_proc(register _Xconst void *string, + register _Xconst void *dlinfo) +{ + return (strcmp((String)string, ((Dl_init*)dlinfo)->name)); +} + +static long +read_int(char *cp, char **cpp) +{ + long value = 0, sign = 1; + + if (*cp == '-') + { + sign = -1; + ++cp; + } + else if (*cp == '+') + ++cp; + value = 0; + while (*cp >= '0' && *cp <= '9') + { + value = value * 10 + *cp - '0'; + ++cp; + } + if (cpp) + *cpp = cp; + return (value * sign); +} + +static void +read_position(char *arg, XawDLPosition *pos) +{ + int ch; + char *str = arg; + + ch = *str; + if (ch == '-' || ch == '+') + { + ++str; + if (ch == '-') + pos->high = True; + pos->pos = read_int(str, NULL); + } + else if (isdigit(ch)) + { + pos->pos = read_int(str, &str); + ch = *str++; + if (ch == '/') + pos->denom = read_int(str, NULL); + } +} + +/* ARGSUSED */ +static void * +_Xaw_Xlib_ArgsInitProc(String proc_name, String *params, Cardinal *num_params, + Screen *screen, Colormap colormap, int depth) +{ + Cardinal id, i; + Dl_init *init; + void *retval = XAWDL_CONVERT_ERROR; + + init = (Dl_init *)bsearch(proc_name, dl_init, + sizeof(dl_init) / sizeof(dl_init[0]), + sizeof(dl_init[0]), + bcmp_cvt_proc); + + id = init->id; + + switch (id) + { + case LINE: + case DRECT: + case FRECT: + if (*num_params == 4) + { + XawDLPosition *pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) * 4); + + for (i = 0; i < 4; i++) + read_position(params[i], &pos[i]); + retval = (void *)pos; + } + break; + case POINT: + case TSORIGIN: + case CLIPORIGIN: + if (*num_params == 2) + { + XawDLPosition *pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) * 2); + + read_position(params[0], &pos[0]); + read_position(params[1], &pos[1]); + retval = (void *)pos; + } + break; + case DLINES: + case FPOLY: + case POINTS: + if (*num_params >= 4 && !(*num_params & 1)) + { + XawDLPositionPtr *pos = XtNew(XawDLPositionPtr); + + pos->pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) * + *num_params); + pos->num_pos = *num_params; + for (i = 0; i < *num_params; i++) + read_position(params[i], &pos->pos[i]); + retval = (void *)pos; + } + break; + case SEGMENTS: + case CLIPRECTS: + if (*num_params >= 4 && !(*num_params % 4)) + { + XawDLPositionPtr *pos = XtNew(XawDLPositionPtr); + + pos->pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) * + *num_params); + pos->num_pos = *num_params; + for (i = 0; i < *num_params; i++) + read_position(params[i], &pos->pos[i]); + retval = (void *)pos; + } + break; + case DARC: + case FARC: + if (*num_params >= 4 && *num_params <= 6) + { + XawDLArcArgs *args = (XawDLArcArgs *)XtCalloc(1, sizeof(XawDLArcArgs)); + + args->angle1 = 0; + args->angle2 = 360; + for (i = 0; i < 4; i++) + read_position(params[i], &args->pos[i]); + if (*num_params > 4) + args->angle1 = read_int(params[4], NULL); + if (*num_params > 5) + args->angle2 = read_int(params[5], NULL); + args->angle1 *= 64; + args->angle2 *= 64; + retval = (void *)args; + } + break; + case GCFG: + case GCBG: + { + XColor xcolor; + + if (*num_params == 1 && + XAllocNamedColor(DisplayOfScreen(screen), colormap, + params[0], &xcolor, &xcolor)) + retval = (void *)xcolor.pixel; + } break; + case MASK: + case UMASK: + if (*num_params == 0) + retval = NULL; + break; + case LWIDTH: + if (*num_params == 1) + retval = (void *)read_int(params[0], NULL); + break; + case ARCMODE: + if (*num_params == 1) + { + if (XmuCompareISOLatin1(params[0], "pieslice") == 0) + retval = (void *)ArcPieSlice; + else if (XmuCompareISOLatin1(params[0], "chord") == 0) + retval = (void *)ArcChord; + } + break; + case COORDMODE: + if (*num_params == 1) + { + if (XmuCompareISOLatin1(params[0], "origin") == 0) + retval = (void *)CoordModeOrigin; + else if (XmuCompareISOLatin1(params[0], "previous") == 0) + retval = (void *)CoordModePrevious; + } + break; + case SHAPEMODE: + if (*num_params == 1) + { + if (XmuCompareISOLatin1(params[0], "complex") == 0) + retval = (void *)Complex; + else if (XmuCompareISOLatin1(params[0], "convex") == 0) + retval = (void *)Convex; + else if (XmuCompareISOLatin1(params[0], "nonconvex") == 0) + retval = (void *)Nonconvex; + } + break; + case LINESTYLE: + if (*num_params == 1) + { + if (XmuCompareISOLatin1(params[0], "solid") == 0) + retval = (void *)LineSolid; + else if (XmuCompareISOLatin1(params[0], "onoffdash") == 0) + retval = (void *)LineOnOffDash; + else if (XmuCompareISOLatin1(params[0], "doubledash") == 0) + retval = (void *)LineDoubleDash; + } + break; + case CAPSTYLE: + if (*num_params == 1) + { + if (XmuCompareISOLatin1(params[0], "notlast") == 0) + retval = (void *)CapNotLast; + else if (XmuCompareISOLatin1(params[0], "butt") == 0) + retval = (void *)CapButt; + else if (XmuCompareISOLatin1(params[0], "round") == 0) + retval = (void *)CapRound; + else if (XmuCompareISOLatin1(params[0], "projecting") == 0) + retval = (void *)CapProjecting; + } + break; + case JOINSTYLE: + if (*num_params == 1) + { + if (XmuCompareISOLatin1(params[0], "miter") == 0) + retval = (void *)JoinMiter; + else if (XmuCompareISOLatin1(params[0], "round") == 0) + retval = (void *)JoinRound; + else if (XmuCompareISOLatin1(params[0], "bevel") == 0) + retval = (void *)JoinBevel; + } + break; + case FILLSTYLE: + if (*num_params == 1) + { + if (*num_params && XmuCompareISOLatin1(params[0], "solid") == 0) + retval = (void *)FillSolid; + else if (*num_params && XmuCompareISOLatin1(params[0], "tiled") == 0) + retval = (void *)FillTiled; + else if (*num_params && XmuCompareISOLatin1(params[0], "stippled") == 0) + retval = (void *)FillStippled; + else if (*num_params && XmuCompareISOLatin1(params[0], "opaquestippled") == 0) + retval = (void *)FillOpaqueStippled; + } + break; + case FILLRULE: + if (*num_params == 1) + { + if (XmuCompareISOLatin1(params[0], "evenodd") == 0) + retval = (void *)EvenOddRule; + else if (XmuCompareISOLatin1(params[0], "winding") == 0) + retval = (void *)WindingRule; + } + break; + case TILE: + if (*num_params == 1) + retval = (void *)XawLoadPixmap(params[0], screen, colormap, depth); + if (retval == NULL) + { + XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0], + XtRPixmap); + retval = XAWDL_CONVERT_ERROR; + } + break; + case STIPPLE: + if (*num_params == 1) + retval = (void *)XawLoadPixmap(params[0], screen, colormap, 1); + if (retval == NULL) + { + XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0], + XtRBitmap); + retval = XAWDL_CONVERT_ERROR; + } + break; + case FUNCTION: + if (*num_params == 1) + { + if (XmuCompareISOLatin1(params[0], "set") == 0) + retval = (void *)GXset; + else if (XmuCompareISOLatin1(params[0], "clear") == 0) + retval = (void *)GXclear; + else if (XmuCompareISOLatin1(params[0], "and") == 0) + retval = (void *)GXand; + else if (XmuCompareISOLatin1(params[0], "andreverse") == 0) + retval = (void *)GXandReverse; + else if (XmuCompareISOLatin1(params[0], "copy") == 0) + retval = (void *)GXcopy; + else if (XmuCompareISOLatin1(params[0], "andinverted") == 0) + retval = (void *)GXandInverted; + else if (XmuCompareISOLatin1(params[0], "noop") == 0) + retval = (void *)GXnoop; + else if (XmuCompareISOLatin1(params[0], "xor") == 0) + retval = (void *)GXxor; + else if (XmuCompareISOLatin1(params[0], "or") == 0) + retval = (void *)GXor; + else if (XmuCompareISOLatin1(params[0], "nor") == 0) + retval = (void *)GXnor; + else if (XmuCompareISOLatin1(params[0], "equiv") == 0) + retval = (void *)GXequiv; + else if (XmuCompareISOLatin1(params[0], "invert") == 0) + retval = (void *)GXinvert; + else if (XmuCompareISOLatin1(params[0], "orreverse") == 0) + retval = (void *)GXorReverse; + else if (XmuCompareISOLatin1(params[0], "copyinverted") == 0) + retval = (void *)GXcopyInverted; + else if (XmuCompareISOLatin1(params[0], "nand") == 0) + retval = (void *)GXnand; + } + break; + case PLANEMASK: + if (*num_params == 1) + retval = (void *)read_int(params[0], NULL); + break; + case DSTRING: + case PSTRING: + if (*num_params == 3) + { + XawDLStringArgs *string = (XawDLStringArgs *) + XtCalloc(1, sizeof(XawDLStringArgs)); + + read_position(params[0], &string->pos[0]); + read_position(params[1], &string->pos[1]); + string->string = XtNewString(params[2]); + string->length = strlen(string->string); + retval = string; + } + break; + case FONT: + if (*num_params == 1) + retval = (void *)XLoadFont(DisplayOfScreen(screen), params[0]); + break; + case DASHES: + if (*num_params && *num_params < 127) + { + char *dashes; + + dashes = XtMalloc(*num_params + 1); + + for (i = 0; i < *num_params; i++) + dashes[i + 1] = read_int(params[i], NULL); + *dashes = *num_params; + retval = dashes; + } + break; + case SUBWMODE: + if (*num_params == 1) + { + if (XmuCompareISOLatin1(params[0], "clipbychildren") == 0) + retval = (void *)ClipByChildren; + else if (XmuCompareISOLatin1(params[0], "includeinferiors") == 0) + retval = (void *)IncludeInferiors; + } + break; + case EXPOSURES: + if (*num_params == 1) + { + if (isdigit(params[0][0]) || params[0][0] == '+' || params[0][0] == '-') + retval = (void *)read_int(params[0], NULL); + else if (XmuCompareISOLatin1(params[0], "true") == 0 || + XmuCompareISOLatin1(params[0], "on") == 0) + retval = (void *)True; + else if (XmuCompareISOLatin1(params[0], "false") == 0 || + XmuCompareISOLatin1(params[0], "off") == 0) + retval = (void *)False; + } + break; + case CLIPMASK: + if (*num_params == 1) + retval = (void *)XawLoadPixmap(params[0], screen, colormap, 1); + if (retval == NULL) + { + retval = XAWDL_CONVERT_ERROR; + XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0], + XtRPixmap); + } + break; + case COPYAREA: + case COPYPLANE: + if (*num_params > 2 && *num_params <= 7 + (id == COPYPLANE)) + { + XawDLCopyArgs *args = (XawDLCopyArgs *) + XtCalloc(1, sizeof(XawDLCopyArgs)); + + retval = args; + if (params[0][0] == '\0' || strcmp(params[0], ".") == 0) + args->pixmap = NULL; + else + { + args->pixmap = XawLoadPixmap(params[0], screen, colormap, id == COPYPLANE ? 1 : depth); + if (args->pixmap == NULL) + { + XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0], + XtRBitmap); + retval = XAWDL_CONVERT_ERROR; + XtFree((char *)args); + } + } + if (retval != XAWDL_CONVERT_ERROR) + { + for (i = 1; i < *num_params && i < 7; i++) + read_position(params[i], &args->pos[i - 1]); + if (*num_params > 7) + args->plane = read_int(params[7], NULL); + } + } + break; + case IMAGE: + if (*num_params > 2 && *num_params <= 7) + { + XawDLImageArgs *args = (XawDLImageArgs *) + XtCalloc(1, sizeof(XawDLImageArgs)); + + retval = args; + args->pixmap = XawLoadPixmap(params[0], screen, colormap, depth); + if (args->pixmap == NULL) + { + XtDisplayStringConversionWarning(DisplayOfScreen(screen), + (String)params[0], XtRPixmap); + retval = XAWDL_CONVERT_ERROR; + XtFree((char *)args); + } + else + { + args->depth = depth; + for (i = 1; i < *num_params && i < 5; i++) + read_position(params[i], &args->pos[i - 1]); + } + } + break; + } + + return (retval); +} + +/* ARGSUSED */ +static void * +_Xaw_Xlib_DataInitProc(String class_name, + Screen *screen, Colormap colormap, int depth) +{ + XawXlibData *data; + Window tmp_win; + + data = (XawXlibData *)XtMalloc(sizeof(XawXlibData)); + + tmp_win = XCreateWindow(DisplayOfScreen(screen), + RootWindowOfScreen(screen), + 0, 0, 1, 1, 1, depth, + InputOutput, (Visual *)CopyFromParent, 0, NULL); + data->mask = 0; + data->gc = XCreateGC(DisplayOfScreen(screen), tmp_win, 0, &data->values); + XDestroyWindow(DisplayOfScreen(screen), tmp_win); + data->shape = Complex; + data->mode = CoordModeOrigin; + data->dashes = NULL; + + return ((void *)data); +} + +/* ARGSUSED */ +static void +_Xaw_Xlib_ArgsDestructor(Display *display, String proc_name, XtPointer args, + String *params, Cardinal *num_params) +{ + Cardinal id; + Dl_init *init; + + init = (Dl_init *)bsearch(proc_name, dl_init, + sizeof(dl_init) / sizeof(dl_init[0]), + sizeof(dl_init[0]), + bcmp_cvt_proc); + + id = init->id; + + switch (id) + { + case LINE: + case DRECT: + case FRECT: + case DARC: + case FARC: + case POINT: + case TSORIGIN: + case DASHES: + case CLIPORIGIN: + case COPYAREA: + case COPYPLANE: + case IMAGE: + XtFree(args); + break; + case DSTRING: + case PSTRING: + { + XawDLStringArgs *string = (XawDLStringArgs *)args; + XtFree(string->string); + XtFree(args); + } break; + case DLINES: + case FPOLY: + case POINTS: + case SEGMENTS: + case CLIPRECTS: + { + XawDLPositionPtr *ptr = (XawDLPositionPtr *)args; + + XtFree((char *)ptr->pos); + XtFree(args); + } break; + } +} + +/* ARGSUSED */ +static void +_Xaw_Xlib_DataDestructor(Display *display, String class_name, XtPointer data) +{ + if (data) + { + XawXlibData *xdata = (XawXlibData *)data; + + XFreeGC(display, xdata->gc); + if (xdata->dashes) + XtFree(xdata->dashes); + XtFree((char *)data); + } +} + +/* Start of DLInfo Management Functions */ +static int +qcmp_dlist_info(register _Xconst void *left, register _Xconst void *right) +{ + return (strcmp((*(XawDLInfo **)left)->name, (*(XawDLInfo **)right)->name)); +} + +Bool XawDeclareDisplayListProc(XawDLClass *lc, String name, + XawDisplayListProc proc) +{ + XawDLInfo *info; + + if (!lc || !proc || !name || name[0] == '\0') + return (False); + + if ((info = _XawFindDLInfo(lc, name)) != NULL) + /* Since the data structures to the displayList classes are(should be) + * opaque, it is not a good idea to allow overriding a displayList + * procedure; it's better to choose another name or class name! + */ + return (False); + + info = (XawDLInfo *)XtMalloc(sizeof(XawDLInfo)); + info->name = XtNewString(name); + info->qname = XrmStringToQuark(info->name); + info->proc = proc; + + if (!lc->num_infos) + { + lc->num_infos = 1; + lc->infos = (XawDLInfo **)XtMalloc(sizeof(XawDLInfo*)); + } + else + { + ++lc->num_infos; + lc->infos = (XawDLInfo **) + XtRealloc((char *)lc->infos, sizeof(XawDLInfo*) * lc->num_infos); + } + lc->infos[lc->num_infos - 1] = info; + + if (lc->num_infos > 1) + qsort(lc->infos, lc->num_infos, sizeof(XawDLInfo*), qcmp_dlist_info); + + return (True); +} + +static int +bcmp_dlist_info(register _Xconst void *string, + register _Xconst void *dlinfo) +{ + return (strcmp((String)string, (*(XawDLClass **)dlinfo)->name)); +} + +static XawDLInfo * +_XawFindDLInfo(XawDLClass *lc, String name) +{ + XawDLInfo **info; + + if (!lc->infos) + return (NULL); + + info = (XawDLInfo **)bsearch(name, lc->infos, lc->num_infos, + sizeof(XawDLInfo*), bcmp_dlist_info); + + return (info ? *info : NULL); +} + +/* Start of DLClass Management Functions */ +XawDLClass * +XawGetDisplayListClass(String name) +{ + return (_XawFindDLClass(name)); +} + +static int +qcmp_dlist_class(register _Xconst void *left, register _Xconst void *right) +{ + return (strcmp((*(XawDLClass **)left)->name, (*(XawDLClass **)right)->name)); +} + +XawDLClass * +XawCreateDisplayListClass(String name, + XawDLArgsInitProc args_init, + XawDLArgsDestructor args_destructor, + XawDLDataInitProc data_init, + XawDLDataDestructor data_destructor) +{ + XawDLClass *lc; + + if (!name || name[0] == '\0') + return (NULL); + + lc = (XawDLClass *)XtMalloc(sizeof(XawDLClass)); + lc->name = XtNewString(name); + lc->infos = NULL; + lc->num_infos = 0; + lc->args_init = args_init; + lc->args_destructor = args_destructor; + lc->data_init = data_init; + lc->data_destructor = data_destructor; + + if (!classes) + { + num_classes = 1; + classes = (XawDLClass **)XtMalloc(sizeof(XawDLClass)); + } + else + { + ++num_classes; + classes = (XawDLClass **)XtRealloc((char *)classes, + sizeof(XawDLClass) * num_classes); + } + classes[num_classes - 1] = lc; + + if (num_classes > 1) + qsort(&classes[0], num_classes, sizeof(XawDLClass*), qcmp_dlist_class); + + return (lc); +} + +static int +bcmp_dlist_class(register _Xconst void *string, + register _Xconst void *dlist) +{ + return (strcmp((String)string, (*(XawDLClass **)dlist)->name)); +} + +static XawDLClass * +_XawFindDLClass(String name) +{ + XawDLClass **lc; + + if (!classes) + return (NULL); + + lc = (XawDLClass **)bsearch(name, &classes[0], num_classes, + sizeof(XawDLClass*), bcmp_dlist_class); + + return (lc ? *lc : NULL); +} + +#endif /* OLDXAW */ diff --git a/src/Form.c b/src/Form.c new file mode 100644 index 0000000..dcc26f3 --- /dev/null +++ b/src/Form.c @@ -0,0 +1,1106 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include "Private.h" + +/* + * Class Methods + */ +static void XawFormChangeManaged(Widget); +static void XawFormClassInitialize(void); +static void XawFormClassPartInitialize(WidgetClass); +static void XawFormConstraintInitialize(Widget, Widget, ArgList, Cardinal*); +static Boolean XawFormConstraintSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static XtGeometryResult XawFormGeometryManager(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawFormInitialize(Widget, Widget, ArgList, Cardinal*); +#ifndef OLDXAW +static void XawFormRealize(Widget, Mask*, XSetWindowAttributes*); +static void XawFormRedisplay(Widget, XEvent*, Region); +#endif +static XtGeometryResult XawFormQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawFormResize(Widget); +static Boolean XawFormSetValues(Widget, Widget, Widget, ArgList, Cardinal*); +static Boolean Layout(FormWidget, unsigned int, unsigned int, Bool); + +/* + * Prototypes + */ +static void _CvtStringToEdgeType(XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr); +static Bool ChangeFormGeometry(Widget, Bool, unsigned int, unsigned int, + Dimension*, Dimension*); +Boolean CvtEdgeTypeToString(Display*, XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr, XtPointer*); +static void LayoutChild(Widget); +static int TransformCoord(int, unsigned int, unsigned int, XtEdgeType); +static void ResizeChildren(Widget); + +/* + * Initialization + */ +#ifndef OLDXAW +static XtActionsRec actions[] = { + {"set-values", XawSetValuesAction}, + {"get-values", XawGetValuesAction}, + {"declare", XawDeclareAction}, + {"call-proc", XawCallProcAction}, +}; +#endif + +static XrmQuark QchainLeft, QchainRight, QchainTop, QchainBottom, Qrubber; + +#define default_value -99999 +#define Offset(field) XtOffsetOf(FormRec, form.field) +static XtResource resources[] = { + { + XtNdefaultDistance, + XtCThickness, + XtRInt, + sizeof(int), + Offset(default_spacing), + XtRImmediate, + (XtPointer)4 + }, +#ifndef OLDXAW + { + XawNdisplayList, + XawCDisplayList, + XawRDisplayList, + sizeof(XawDisplayList*), + Offset(display_list), + XtRImmediate, + NULL + }, +#endif +}; +#undef Offset + +#define defEdge XtRubber + +#define Offset(field) XtOffsetOf(FormConstraintsRec, form.field) +static XtResource formConstraintResources[] = { + { + XtNtop, + XtCEdge, + XtREdgeType, + sizeof(XtEdgeType), + Offset(top), + XtRImmediate, + (XtPointer)defEdge + }, + { + XtNbottom, + XtCEdge, + XtREdgeType, + sizeof(XtEdgeType), + Offset(bottom), + XtRImmediate, + (XtPointer)defEdge + }, + { + XtNleft, + XtCEdge, + XtREdgeType, + sizeof(XtEdgeType), + Offset(left), + XtRImmediate, + (XtPointer)defEdge + }, + { + XtNright, + XtCEdge, + XtREdgeType, + sizeof(XtEdgeType), + Offset(right), + XtRImmediate, + (XtPointer)defEdge + }, + { + XtNhorizDistance, + XtCThickness, + XtRInt, + sizeof(int), + Offset(dx), + XtRImmediate, + (XtPointer)default_value + }, + { + XtNfromHoriz, + XtCWidget, + XtRWidget, + sizeof(Widget), + Offset(horiz_base), + XtRWidget, + NULL + }, + { + XtNvertDistance, + XtCThickness, + XtRInt, + sizeof(int), + Offset(dy), + XtRImmediate, + (XtPointer)default_value + }, + { + XtNfromVert, + XtCWidget, + XtRWidget, + sizeof(Widget), + Offset(vert_base), + XtRWidget, + NULL + }, + { + XtNresizable, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + Offset(allow_resize), + XtRImmediate, + (XtPointer)False + }, +}; +#undef Offset + +FormClassRec formClassRec = { + /* core */ + { + (WidgetClass)&constraintClassRec, /* superclass */ + "Form", /* class_name */ + sizeof(FormRec), /* widget_size */ + XawFormClassInitialize, /* class_initialize */ + XawFormClassPartInitialize, /* class_part_init */ + False, /* class_inited */ + XawFormInitialize, /* initialize */ + NULL, /* initialize_hook */ +#ifndef OLDXAW + XawFormRealize, /* realize */ + actions, /* actions */ + XtNumber(actions), /* num_actions */ +#else + XtInheritRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ +#endif + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + XawFormResize, /* resize */ +#ifndef OLDXAW + XawFormRedisplay, /* expose */ +#else + XtInheritExpose, /* expose */ +#endif + XawFormSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XawFormQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* composite */ + { + XawFormGeometryManager, /* geometry_manager */ + XawFormChangeManaged, /* change_managed */ + XtInheritInsertChild, /* insert_child */ + XtInheritDeleteChild, /* delete_child */ + NULL, /* extension */ + }, + /* constraint */ + { + formConstraintResources, /* subresourses */ + XtNumber(formConstraintResources), /* subresource_count */ + sizeof(FormConstraintsRec), /* constraint_size */ + XawFormConstraintInitialize, /* initialize */ + NULL, /* destroy */ + XawFormConstraintSetValues, /* set_values */ + NULL, /* extension */ + }, + /* form */ + { + Layout, /* layout */ + }, +}; + +WidgetClass formWidgetClass = (WidgetClass)&formClassRec; + +/* + * Implementation + */ +#ifndef OLDXAW +static void +XawFormRealize(Widget w, Mask *mask, XSetWindowAttributes *attr) +{ + XawPixmap *pixmap; + + (*formWidgetClass->core_class.superclass->core_class.realize)(w, mask, attr); + + if (w->core.background_pixmap > XtUnspecifiedPixmap) { + pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w), + w->core.colormap, w->core.depth); + if (pixmap && pixmap->mask) + XawReshapeWidget(w, pixmap); + } +} + +static void +XawFormRedisplay(Widget w, XEvent *event, Region region) +{ + FormWidget xaw = (FormWidget)w; + + if (xaw->form.display_list) + XawRunDisplayList(w, xaw->form.display_list, event, region); +} +#endif + +/*ARGSUSED*/ +static void +_CvtStringToEdgeType(XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal) +{ + static XtEdgeType edgeType; + XrmQuark q; + char name[12]; + + XmuNCopyISOLatin1Lowered(name, (char*)fromVal->addr, sizeof(name)); + q = XrmStringToQuark(name); + + if (q == QchainLeft) + edgeType = XtChainLeft; + else if (q == QchainRight) + edgeType = XtChainRight; + else if (q == QchainTop) + edgeType = XtChainTop; + else if (q == QchainBottom) + edgeType = XtChainBottom; + else if (q == Qrubber) + edgeType = XtRubber; + else { + XtStringConversionWarning(fromVal->addr, XtREdgeType); + toVal->size = 0; + toVal->addr = NULL; + return; + } + + toVal->size = sizeof(XtEdgeType); + toVal->addr = (XPointer)&edgeType; +} + +/*ARGSUSED*/ +Boolean +CvtEdgeTypeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal, XtPointer *data) +{ + static String buffer; + Cardinal size; + + switch (*(XtEdgeType *)fromVal->addr) { + case XtChainLeft: + buffer = XtEchainLeft; + break; + case XtChainRight: + buffer = XtEchainRight; + break; + case XtChainTop: + buffer = XtEchainTop; + break; + case XtChainBottom: + buffer = XtEchainBottom; + break; + case XtRubber: + buffer = XtErubber; + break; + default: + XawTypeToStringWarning(dpy, XtREdgeType); + toVal->addr = NULL; + toVal->size = 0; + return (False); + } + + size = strlen(buffer) + 1; + if (toVal->addr != NULL) { + if (toVal->size < size) { + toVal->size = size; + return (False); + } + strcpy((char *)toVal->addr, buffer); + } + else + toVal->addr = (XPointer)buffer; + toVal->size = sizeof(String); + + return (True); +} + +static void +XawFormClassInitialize(void) +{ + static XtConvertArgRec parentCvtArgs[] = { + {XtBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.parent), + sizeof(Widget)} + }; + + char name[12]; + + XawInitializeWidgetSet(); + XmuNCopyISOLatin1Lowered(name, XtEchainLeft, sizeof(name)); + QchainLeft = XrmStringToQuark(name); + XmuNCopyISOLatin1Lowered(name, XtEchainRight, sizeof(name)); + QchainRight = XrmStringToQuark(name); + XmuNCopyISOLatin1Lowered(name, XtEchainTop, sizeof(name)); + QchainTop = XrmStringToQuark(name); + XmuNCopyISOLatin1Lowered(name, XtEchainBottom, sizeof(name)); + QchainBottom = XrmStringToQuark(name); + XmuNCopyISOLatin1Lowered(name, XtErubber, sizeof(name)); + Qrubber = XrmStringToQuark(name); + + XtAddConverter(XtRString, XtREdgeType, _CvtStringToEdgeType, NULL, 0); + XtSetTypeConverter(XtREdgeType, XtRString, CvtEdgeTypeToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRString, XtRWidget, XmuNewCvtStringToWidget, + parentCvtArgs, XtNumber(parentCvtArgs), XtCacheNone, + NULL); + XtSetTypeConverter(XtRWidget, XtRString, XmuCvtWidgetToString, + NULL, 0, XtCacheNone, NULL); +} + +static void +XawFormClassPartInitialize(WidgetClass cclass) +{ + FormWidgetClass c = (FormWidgetClass)cclass; + FormWidgetClass super = (FormWidgetClass)c->core_class.superclass; + + if (c->form_class.layout == XtInheritLayout) + c->form_class.layout = super->form_class.layout; +} + +/*ARGSUSED*/ +static void +XawFormInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + FormWidget fw = (FormWidget)cnew; + + fw->form.old_width = fw->form.old_height = 0; + fw->form.no_refigure = False; + fw->form.needs_relayout = False; + fw->form.resize_in_layout = True; + fw->form.resize_is_no_op = False; +} + +/* + * Function: + * ChangeFormGeometry + * + * Parameters: + * w - Form widget + * query_only - is only a query? + * width - new width and height + * height - "" + * ret_width - actual size the form is allowed to resize to (return) + * ret_height - "" + * + * Description: + * Ask the parent to change the form widget's geometry. + * + * Returns: + * True of children may always be resized + */ +static Bool +ChangeFormGeometry(Widget w, Bool query_only, + unsigned int width, unsigned int height, + Dimension *ret_width, Dimension *ret_height) +{ + FormWidget fw = (FormWidget)w; + Boolean always_resize_children; + XtGeometryResult result; + XtWidgetGeometry request, return_request; + + /* + * If we are already at the desired size then there is no need + * to ask our parent of we can change size + */ + if (width == XtWidth(fw) && height == XtHeight(fw)) + return (True); + + request.width = width; + request.height = height; + request.request_mode = CWWidth | CWHeight; + if (query_only) + request.request_mode |= XtCWQueryOnly; + + /* + * Do no invoke the resize rules if our size changes here + */ + fw->form.resize_is_no_op = True; + + result = XtMakeGeometryRequest(w, &request, &return_request); + if (result == XtGeometryAlmost) { + request = return_request; + (void)XtMakeGeometryRequest(w, &request, &return_request); + always_resize_children = False; + } + else + always_resize_children = result == XtGeometryYes; + + fw->form.resize_is_no_op = False; + + if (ret_width != NULL) + *ret_width = request.width; + if (ret_height != NULL) + *ret_height = request.height; + + return (always_resize_children); +} + +/* + * Function: + * Layout + * + * Parameters: + * fw - Form widget + * width - unused + * height - "" + * force_relayout - will force the children to be moved, even if some + * go past the edge of the form + * + * Description: + * Moves all the children around. + * + * Returns: + * True if the children are allowed to move from their + * current locations to the new ones. + */ +/*ARGSUSED*/ +static Boolean +Layout(FormWidget fw, unsigned int width, unsigned int height, + Bool force_relayout) +{ + int num_children = fw->composite.num_children; + WidgetList children = fw->composite.children; + Widget *childP; + Dimension maxx, maxy; + Boolean ret_val; + + for (childP = children; childP - children < num_children; childP++) { + FormConstraints form = (FormConstraints)(*childP)->core.constraints; + form->form.layout_state = LayoutPending; + } + + maxx = maxy = 1; + for (childP = children; childP - children < num_children; childP++) { + if (XtIsManaged(*childP)) { + FormConstraints form; + Position x, y; + + form = (FormConstraints)(*childP)->core.constraints; + + LayoutChild(*childP); + + x = form->form.new_x + XtWidth(*childP) + + (XtBorderWidth(*childP) << 1); + if (x > (int)maxx) + maxx = x; + + y = form->form.new_y + XtHeight(*childP) + + (XtBorderWidth(*childP) << 1); + if (y > (int)maxy) + maxy = y; + } + } + + fw->form.preferred_width = (maxx += fw->form.default_spacing); + fw->form.preferred_height = (maxy += fw->form.default_spacing); + + if (fw->form.resize_in_layout) { + Boolean always_resize_children; + + always_resize_children = + ChangeFormGeometry((Widget)fw, False, maxx, maxy, NULL, NULL); + +#ifdef OLDXAW + fw->form.old_width = fw->core.width; + fw->form.old_height = fw->core.height; +#endif + + if (force_relayout) + ret_val = True; + else + ret_val = always_resize_children || + (XtWidth(fw) >= maxx && XtHeight(fw) >= maxy); + + if (ret_val) + ResizeChildren((Widget)fw); + } + else + ret_val = False; + + fw->form.needs_relayout = False; + + return (ret_val); +} + +/* + * Function: + * ResizeChildren + * + * Parameters: + * w - form widget + * + * Description: + * Resizes all children to new_x and new_y. + */ +static void +ResizeChildren(Widget w) +{ + FormWidget fw = (FormWidget)w; + int num_children = fw->composite.num_children; + WidgetList children = fw->composite.children; + Widget *childP; + + for (childP = children; childP - children < num_children; childP++) { + FormConstraints form; + Position x, y; + + if (!XtIsManaged(*childP)) + continue; + + form = (FormConstraints)(*childP)->core.constraints; + + if (fw->form.old_width && fw->form.old_height) { + x = TransformCoord(form->form.new_x, fw->form.old_width, + XtWidth(fw), form->form.left); + y = TransformCoord(form->form.new_y, fw->form.old_height, + XtHeight(fw), form->form.top); + } + else { + x = form->form.new_x; + y = form->form.new_y; + } + + if (fw->form.no_refigure) { + /* + * I am changing the widget wrapper w/o modifing the window. This is + * risky, but I can get away with it since I am the parent of this + * widget, and he must ask me for any geometry changes + * + * The window will be updated when no_refigure is set back to False + */ + XtX(*childP) = x; + XtY(*childP) = y; + } + else + XtMoveWidget(*childP, x, y); + } +} + +static void +LayoutChild(Widget w) +{ + FormConstraints form = (FormConstraints)w->core.constraints; + Widget ref; + + switch (form->form.layout_state) { + case LayoutPending: + form->form.layout_state = LayoutInProgress; + break; + case LayoutDone: + return; + case LayoutInProgress: { + String subs[2]; + Cardinal num_subs = 2; + subs[0] = w->core.name; + subs[1] = w->core.parent->core.name; + + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "constraintLoop", "xawFormLayout", "XawToolkitError", + "constraint loop detected while laying out " + "child '%s' in FormWidget '%s'", + subs, &num_subs); + } return; + } + + form->form.new_x = form->form.dx; + form->form.new_y = form->form.dy; + if ((ref = form->form.horiz_base) != NULL) { + FormConstraints ref_form = (FormConstraints)ref->core.constraints; + + LayoutChild(ref); + form->form.new_x += ref_form->form.new_x + XtWidth(ref) + + (XtBorderWidth(ref) << 1); + } + if ((ref = form->form.vert_base) != NULL) { + FormConstraints ref_form = (FormConstraints)ref->core.constraints; + + LayoutChild(ref); + form->form.new_y += ref_form->form.new_y + XtHeight(ref) + + (XtBorderWidth(ref) << 1); + } + + form->form.layout_state = LayoutDone; +} + +static int +TransformCoord(int loc, unsigned int old, unsigned int cnew, XtEdgeType type) +{ + if (type == XtRubber) { + if ((int)old > 0) + loc = (int)(loc * ((double)cnew / (double)old)); + } + else if (type == XtChainBottom || type == XtChainRight) + loc += (int)cnew - (int)old; + + return (loc); +} + +static void +XawFormResize(Widget w) +{ + FormWidget fw = (FormWidget)w; + WidgetList children = fw->composite.children; + int num_children = fw->composite.num_children; + Widget *childP; + int x, y; + int width, height; + Boolean unmap = XtIsRealized(w) && w->core.mapped_when_managed && + XtIsManaged(w); + + if (unmap) + XtUnmapWidget(w); + + if (!fw->form.resize_is_no_op) + for (childP = children; childP - children < num_children; childP++) { + FormConstraints form = (FormConstraints)(*childP)->core.constraints; + + if (!XtIsManaged(*childP)) + continue; + +#ifndef OLDXAW + x = TransformCoord(form->form.virtual_x, fw->form.old_width, + XtWidth(fw), form->form.left); + y = TransformCoord(form->form.virtual_y, fw->form.old_height, + XtHeight(fw), form->form.top); + width = TransformCoord(form->form.virtual_x + + form->form.virtual_width + + (XtBorderWidth(*childP) << 1), + fw->form.old_width, XtWidth(fw), + form->form.right) - + (x + (XtBorderWidth(*childP) << 1)); + height = TransformCoord(form->form.virtual_y + + form->form.virtual_height + + (XtBorderWidth(*childP) << 1), + fw->form.old_height, XtHeight(fw), + form->form.bottom) - + (y + (XtBorderWidth(*childP) << 1)); +#else + x = TransformCoord(XtX(*childP), fw->form.old_width, + XtWidth(fw), form->form.left); + y = TransformCoord(XtY(*childP), fw->form.old_height, + XtHeight(fw), form->form.top); + width = TransformCoord(XtX(*childP) + form->form.virtual_width + + (XtBorderWidth(*childP) << 1), + fw->form.old_width, XtWidth(fw), + form->form.right) - + (x + (XtBorderWidth(*childP) << 1)); + height = TransformCoord(XtY(*childP) + form->form.virtual_height + + (XtBorderWidth(*childP) << 1), + fw->form.old_height, XtHeight(fw), + form->form.bottom) - + (y + (XtBorderWidth(*childP) << 1)); + form->form.virtual_width = width; + form->form.virtual_height = height; +#endif + + width = width < 1 ? 1 : width; + height = height < 1 ? 1 : height; + + XtConfigureWidget(*childP, x, y, width, height, + XtBorderWidth(*childP)); + } + + if (unmap) + XtMapWidget(w); + +#ifdef OLDXAW + fw->form.old_width = XtWidth(fw); + fw->form.old_height = XtHeight(fw); +#endif +} + +/*ARGSUSED*/ +static XtGeometryResult +XawFormGeometryManager(Widget w, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + Dimension old_width, old_height; + FormWidget fw = (FormWidget)XtParent(w); + FormConstraints form = (FormConstraints)w->core.constraints; + XtWidgetGeometry allowed; + XtGeometryResult ret_val; + + if ((request->request_mode & (unsigned)~(XtCWQueryOnly | CWWidth | CWHeight)) + || !form->form.allow_resize) { + /* If GeometryManager is invoked during a SetValues call on a child + * then it is necessary to compute a new layout if ConstraintSetValues + * allowed any constraint changes + */ + if (fw->form.needs_relayout) + (*((FormWidgetClass)fw->core.widget_class)->form_class.layout) + (fw, 0, 0, True); + return (XtGeometryNo); + } + + if (request->request_mode & CWWidth) + allowed.width = request->width; + else + allowed.width = XtWidth(w); + + if (request->request_mode & CWHeight) + allowed.height = request->height; + else + allowed.height = XtHeight(w); + + if (allowed.width == XtWidth(w) && allowed.height == XtHeight(w)) { + /* If GeometryManager is invoked during a SetValues call on a child + * then it is necessary to compute a new layout if ConstraintSetValues + * allowed any constraint changes + */ + if (fw->form.needs_relayout) + (*((FormWidgetClass)fw->core.widget_class)->form_class.layout) + (fw, 0, 0, True); + return (XtGeometryNo); + } + + /* + * Remember the old size, and then set the size to the requested size + */ + old_width = XtWidth(w); + old_height = XtHeight(w); + XtWidth(w) = allowed.width; + XtHeight(w) = allowed.height; + + if (request->request_mode & XtCWQueryOnly) { + Boolean always_resize_children; + Dimension ret_width, ret_height; + + fw->form.resize_in_layout = False; + + (*((FormWidgetClass)fw->core.widget_class)->form_class.layout) + (fw, XtWidth(w), XtHeight(w), False); + + /* + * Reset the size of this child back to what it used to be + */ + XtWidth(w) = old_width; + XtHeight(w) = old_height; + + fw->form.resize_in_layout = True; + + always_resize_children = ChangeFormGeometry(w, True, + fw->form.preferred_width, + fw->form.preferred_height, + &ret_width, &ret_height); + + if (always_resize_children + || (ret_width >= fw->form.preferred_width + && ret_height >= fw->form.preferred_height)) + ret_val = XtGeometryYes; + else + ret_val = XtGeometryNo; + } + else { + if ((*((FormWidgetClass)fw->core.widget_class)->form_class.layout) + (fw, XtWidth(w), XtHeight(w), False)) { + Widget *childP; + int num_children = fw->composite.num_children; + WidgetList children = fw->composite.children; + + if (fw->form.no_refigure) { + /* + * I am changing the widget wrapper w/o modifing the window. + * This is risky, but I can get away with it since I am the + * parent of this widget, and he must ask me for any geometry + * changes + * + * The window will be updated when no_refigure is set back + * to False + */ + form->form.deferred_resize = True; + ret_val = XtGeometryDone; + } + else + ret_val = XtGeometryYes; + + /* + * Resets everything. + */ + fw->form.old_width = XtWidth(fw); + fw->form.old_height = XtHeight(fw); + for (childP = children; childP - children < num_children; childP++) { + Widget nw = *childP; + + if (XtIsManaged(nw)) { + FormConstraints nform = (FormConstraints)nw->core.constraints; + +#ifndef OLDXAW + nform->form.virtual_x = XtX(nw); + nform->form.virtual_y = XtY(nw); +#endif + nform->form.virtual_width = XtWidth(nw); + nform->form.virtual_height = XtHeight(nw); + } + } + } + else { + XtWidth(w) = old_width; + XtHeight(w) = old_height; + ret_val = XtGeometryNo; + } + } + + return (ret_val); +} + +/*ARGSUSED*/ +static Boolean +XawFormSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ +#ifndef OLDXAW + FormWidget f_old = (FormWidget)current; + FormWidget f_new = (FormWidget)cnew; + + if (f_old->core.background_pixmap != f_new->core.background_pixmap) { + XawPixmap *opix, *npix; + + opix = XawPixmapFromXPixmap(f_old->core.background_pixmap, XtScreen(f_old), + f_old->core.colormap, f_old->core.depth); + npix = XawPixmapFromXPixmap(f_new->core.background_pixmap, XtScreen(f_new), + f_new->core.colormap, f_new->core.depth); + if ((npix && npix->mask) || (opix && opix->mask)) + XawReshapeWidget(cnew, npix); + } +#endif /* OLDXAW */ + + return (False); +} + +/* ARGSUSED */ +static void +XawFormConstraintInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + FormConstraints form = (FormConstraints)cnew->core.constraints; + FormWidget fw = (FormWidget)cnew->core.parent; + +#ifndef OLDXAW + form->form.virtual_x = XtX(cnew); + form->form.virtual_y = XtY(cnew); +#endif + form->form.virtual_width = XtWidth(cnew); + form->form.virtual_height = XtHeight(cnew); + + if (form->form.dx == default_value) + form->form.dx = fw->form.default_spacing; + + if (form->form.dy == default_value) + form->form.dy = fw->form.default_spacing; + + form->form.deferred_resize = False; +} + +/*ARGSUSED*/ +static Boolean +XawFormConstraintSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + FormConstraints cfc = (FormConstraints)current->core.constraints; + FormConstraints nfc = (FormConstraints)cnew->core.constraints; + + if (cfc->form.top != nfc->form.top || cfc->form.bottom != nfc->form.bottom + || cfc->form.left != nfc->form.left || cfc->form.right != nfc->form.right + || cfc->form.dx != nfc->form.dx || cfc->form.dy != nfc->form.dy + || cfc->form.horiz_base != nfc->form.horiz_base + || cfc->form.vert_base != nfc->form.vert_base) { + FormWidget fp = (FormWidget)XtParent(cnew); + + /* If there are no subclass ConstraintSetValues procedures remaining + * to be invoked, and if there is no geometry request about to be + * made, then invoke the new layout now; else defer it + */ + if (XtClass(XtParent(cnew)) == formWidgetClass + && XtX(current) == XtX(cnew) + && XtY(current) == XtY(cnew) + && XtWidth(current) == XtWidth(cnew) + && XtHeight(current) == XtHeight(cnew) + && XtBorderWidth(current) == XtBorderWidth(cnew)) + Layout(fp, 0, 0, True); + else + fp->form.needs_relayout = True; + } + + return (False); +} + +static void +XawFormChangeManaged(Widget w) +{ + FormWidget fw = (FormWidget)w; + FormConstraints form; + WidgetList children, childP; + int num_children = fw->composite.num_children; + Widget child; + + (*((FormWidgetClass)w->core.widget_class)->form_class.layout) + (fw, XtWidth(w), XtHeight(w), True); + + fw->form.old_width = XtWidth(w); + fw->form.old_height = XtHeight(w); + for (children = childP = fw->composite.children; + childP - children < num_children; + childP++) { + child = *childP; + if (!XtIsManaged(child)) + continue; + form = (FormConstraints)child->core.constraints; +#ifndef OLDXAW + form->form.virtual_x = XtX(child); + form->form.virtual_y = XtY(child); +#endif + form->form.virtual_width = XtWidth(child); + form->form.virtual_height = XtHeight(child); + } +} + +static XtGeometryResult +XawFormQueryGeometry(Widget widget, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + FormWidget w = (FormWidget)widget; + + reply->width = w->form.preferred_width; + reply->height = w->form.preferred_height; + reply->request_mode = CWWidth | CWHeight; + + if ((request->request_mode & (CWWidth | CWHeight)) == (CWWidth | CWHeight) + && request->width == reply->width + && request->height == reply->height) + return (XtGeometryYes); + else if (reply->width == XtWidth(w) && reply->height == XtHeight(w)) + return (XtGeometryNo); + + return (XtGeometryAlmost); +} + +/* + * Public routines + */ +/* + * Set or reset figuring (ignored if not realized) + */ +void +XawFormDoLayout(Widget w, +#if NeedWidePrototypes + Bool force +#else + Boolean force +#endif +) +{ + Widget *childP; + FormWidget fw = (FormWidget)w; + int num_children = fw->composite.num_children; + WidgetList children = fw->composite.children; + + if ((fw->form.no_refigure = !force) == True || !XtIsRealized(w)) + return; + + for (childP = children; childP - children < num_children; childP++) { + Widget nw = *childP; + + if (XtIsManaged(nw)) { + FormConstraints form = (FormConstraints)nw->core.constraints; + + /* + * Xt Configure widget is too smart, and optimizes out + * my changes + */ + XMoveResizeWindow(XtDisplay(nw), XtWindow(nw), + XtX(nw), XtY(nw), XtWidth(nw), XtHeight(nw)); + + if (form) + if (form->form.deferred_resize && + XtClass(nw)->core_class.resize != NULL) { + (*(XtClass(nw)->core_class.resize))(nw); + form->form.deferred_resize = False; + } + } + } +} diff --git a/src/Grip.c b/src/Grip.c new file mode 100644 index 0000000..85f021b --- /dev/null +++ b/src/Grip.c @@ -0,0 +1,185 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Grip.c - Grip Widget (Used by Paned Widget) + * + */ +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include + +/* + * Prototypes + */ +static void +GripAction(Widget, XEvent*, String*, Cardinal*); + +/* + * Initialization + */ +static XtResource resources[] = { + { + XtNwidth, + XtCWidth, + XtRDimension, + sizeof(Dimension), + XtOffsetOf(GripRec, core.width), + XtRImmediate, + (XtPointer)DEFAULT_GRIP_SIZE + }, + { + XtNheight, + XtCHeight, + XtRDimension, + sizeof(Dimension), + XtOffsetOf(GripRec, core.height), + XtRImmediate, + (XtPointer)DEFAULT_GRIP_SIZE + }, + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + XtOffsetOf(GripRec, core.background_pixel), + XtRString, + XtDefaultForeground + }, + { + XtNborderWidth, + XtCBorderWidth, + XtRDimension, + sizeof(Dimension), + XtOffsetOf(GripRec, core.border_width), + XtRImmediate, + (XtPointer)0 + }, + { + XtNcallback, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + XtOffsetOf(GripRec, grip.grip_action), + XtRCallback, + NULL + }, +}; + +static XtActionsRec actionsList[] = +{ + {"GripAction", GripAction}, +}; + +#define Superclass (&simpleClassRec) + +GripClassRec gripClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "Grip", /* class name */ + sizeof(GripRec), /* size */ + XawInitializeWidgetSet, /* class initialize */ + NULL, /* class_part_init */ + False, /* class_inited */ + NULL, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + actionsList, /* actions */ + XtNumber(actionsList), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + NULL, /* resize */ + XtInheritExpose, /* expose */ + NULL, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* grip */ + { + NULL, /* extension */ + } +}; + +WidgetClass gripWidgetClass = (WidgetClass)&gripClassRec; + +/* + * Implementation + */ +static void +GripAction(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + XawGripCallDataRec call_data; + + call_data.event = event; + call_data.params = params; + call_data.num_params = *num_params; + + XtCallCallbacks(widget, XtNcallback, (XtPointer)&call_data); +} diff --git a/src/Label.c b/src/Label.c new file mode 100644 index 0000000..e304636 --- /dev/null +++ b/src/Label.c @@ -0,0 +1,821 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#define streq(a, b) (strcmp((a), (b)) == 0) + +#define MULTI_LINE_LABEL 32767 + +#ifdef CRAY +#define WORD64 +#endif + +/* + * Class Methods + */ +static void XawLabelClassInitialize(void); +static void XawLabelDestroy(Widget); +static void XawLabelInitialize(Widget, Widget, ArgList, Cardinal*); +static XtGeometryResult XawLabelQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawLabelRedisplay(Widget, XEvent*, Region); +static void XawLabelResize(Widget); +static Boolean XawLabelSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * Prototypes + */ +#ifdef WORD64 +static int _XawLabelWidth16(XFontStruct*, char*, int); +static void _XawLabelDraw16(Display*, Drawable, GC, int, int, char*, int); +#endif +static void compute_bitmap_offsets(LabelWidget); +static void GetGrayGC(LabelWidget); +static void GetNormalGC(LabelWidget); +static void _Reposition(LabelWidget, unsigned int, unsigned int, + Position*, Position*); +static void set_bitmap_info(LabelWidget); +static void SetTextWidthAndHeight(LabelWidget); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(LabelRec, field) +static XtResource resources[] = { + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(label.foreground), + XtRString, + XtDefaultForeground + }, + { + XtNfont, + XtCFont, + XtRFontStruct, + sizeof(XFontStruct*), + offset(label.font), + XtRString, + XtDefaultFont + }, + { + XtNfontSet, + XtCFontSet, + XtRFontSet, + sizeof(XFontSet), + offset(label.fontset), + XtRString, + XtDefaultFontSet + }, + { + XtNlabel, + XtCLabel, + XtRString, + sizeof(String), + offset(label.label), + XtRString, + NULL + }, + { + XtNencoding, + XtCEncoding, + XtRUnsignedChar, + sizeof(unsigned char), + offset(label.encoding), + XtRImmediate, + (XtPointer)XawTextEncoding8bit + }, + { + XtNjustify, + XtCJustify, + XtRJustify, + sizeof(XtJustify), + offset(label.justify), + XtRImmediate, + (XtPointer)XtJustifyCenter + }, + { + XtNinternalWidth, + XtCWidth, + XtRDimension, + sizeof(Dimension), + offset(label.internal_width), + XtRImmediate, + (XtPointer)4 + }, + { + XtNinternalHeight, + XtCHeight, + XtRDimension, + sizeof(Dimension), + offset(label.internal_height), + XtRImmediate, + (XtPointer)2 + }, + { + XtNleftBitmap, + XtCLeftBitmap, + XtRBitmap, + sizeof(Pixmap), + offset(label.left_bitmap), + XtRImmediate, + (XtPointer)None + }, + { + XtNbitmap, + XtCPixmap, + XtRBitmap, + sizeof(Pixmap), + offset(label.pixmap), + XtRImmediate, + (XtPointer)None + }, + { + XtNresize, + XtCResize, + XtRBoolean, + sizeof(Boolean), + offset(label.resize), + XtRImmediate, + (XtPointer)True + }, + { + XtNlabelX, + XtCPosition, + XtRPosition, + sizeof(Position), + offset(label.label_x), + XtRImmediate, + (XtPointer)0 + }, + { + XtNlabelY, + XtCPosition, + XtRPosition, + sizeof(Position), + offset(label.label_y), + XtRImmediate, + (XtPointer)0 + }, +}; +#undef offset + +#define Superclass (&simpleClassRec) +LabelClassRec labelClassRec = { + /* core */ + { + (WidgetClass)&simpleClassRec, /* superclass */ + "Label", /* class_name */ + sizeof(LabelRec), /* widget_size */ + XawLabelClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawLabelInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawLabelDestroy, /* destroy */ + XawLabelResize, /* resize */ + XawLabelRedisplay, /* expose */ + XawLabelSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XawLabelQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* label */ + { + NULL, /* extension */ + } +}; + +WidgetClass labelWidgetClass = (WidgetClass)&labelClassRec; + +/* + * Implementation + */ +static void +XawLabelClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtAddConverter(XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0); + XtSetTypeConverter(XtRJustify, XtRString, XmuCvtJustifyToString, + NULL, 0, XtCacheNone, NULL); +} + +#ifndef WORD64 +#define TXT16 XChar2b +#else +#define TXT16 char + +static XChar2b *buf2b; +static int buf2blen = 0; + +static int +_XawLabelWidth16(XFontStruct *fs, char *str, int n) +{ + int i; + XChar2b *ptr; + + if (n > buf2blen) { + buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); + buf2blen = n; + } + for (ptr = buf2b, i = n; --i >= 0; ptr++) { + ptr->byte1 = *str++; + ptr->byte2 = *str++; + } + + return (XTextWidth16(fs, buf2b, n)); +} + +static void +_XawLabelDraw16(Display *dpy, Drawable d, GC gc, int x, int y, + char *str, int n) +{ + int i; + XChar2b *ptr; + + if (n > buf2blen) { + buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); + buf2blen = n; + } + for (ptr = buf2b, i = n; --i >= 0; ptr++) { + ptr->byte1 = *str++; + ptr->byte2 = *str++; + } + XDrawString16(dpy, d, gc, x, y, buf2b, n); +} + +#define XTextWidth16 _XawLabelWidth16 +#define XDrawString16 _XawLabelDraw16 +#endif /* WORD64 */ + +/* + * Calculate width and height of displayed text in pixels + */ +static void +SetTextWidthAndHeight(LabelWidget lw) +{ + XFontStruct *fs = lw->label.font; + char *nl; + + if (lw->label.pixmap != None) { + Window root; + int x, y; + unsigned int width, height, bw, depth; + + if (XGetGeometry(XtDisplay(lw), lw->label.pixmap, &root, &x, &y, + &width, &height, &bw, &depth)) { + lw->label.label_height = height; + lw->label.label_width = width; + lw->label.label_len = depth; + return; + } + } + if (lw->simple.international == True) { + XFontSet fset = lw->label.fontset; + XFontSetExtents *ext = XExtentsOfFontSet(fset); + + lw->label.label_height = ext->max_ink_extent.height; + if (lw->label.label == NULL) { + lw->label.label_len = 0; + lw->label.label_width = 0; + } + else if ((nl = index(lw->label.label, '\n')) != NULL) { + char *label; + + lw->label.label_len = MULTI_LINE_LABEL; + lw->label.label_width = 0; + for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { + int width = XmbTextEscapement(fset, label, (int)(nl - label)); + + if (width > (int)lw->label.label_width) + lw->label.label_width = width; + label = nl + 1; + if (*label) + lw->label.label_height += ext->max_ink_extent.height; + } + if (*label) { + int width = XmbTextEscapement(fset, label, strlen(label)); + + if (width > (int)lw->label.label_width) + lw->label.label_width = width; + } + } + else { + lw->label.label_len = strlen(lw->label.label); + lw->label.label_width = + XmbTextEscapement(fset, lw->label.label, lw->label.label_len); + } + } + else { + lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent; + if (lw->label.label == NULL) { + lw->label.label_len = 0; + lw->label.label_width = 0; + } + else if ((nl = index(lw->label.label, '\n')) != NULL) { + char *label; + + lw->label.label_len = MULTI_LINE_LABEL; + lw->label.label_width = 0; + for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { + int width; + + if (lw->label.encoding) + width = XTextWidth16(fs, (TXT16*)label, (int)(nl - label) / 2); + else + width = XTextWidth(fs, label, (int)(nl - label)); + if (width > (int)lw->label.label_width) + lw->label.label_width = width; + label = nl + 1; + if (*label) + lw->label.label_height += + fs->max_bounds.ascent + fs->max_bounds.descent; + } + if (*label) { + int width = XTextWidth(fs, label, strlen(label)); + + if (lw->label.encoding) + width = XTextWidth16(fs, (TXT16*)label, strlen(label) / 2); + else + width = XTextWidth(fs, label, strlen(label)); + if (width > (int) lw->label.label_width) + lw->label.label_width = width; + } + } + else { + lw->label.label_len = strlen(lw->label.label); + if (lw->label.encoding) + lw->label.label_width = + XTextWidth16(fs, (TXT16*)lw->label.label, + (int)lw->label.label_len / 2); + else + lw->label.label_width = + XTextWidth(fs, lw->label.label, (int)lw->label.label_len); + } + } +} + +static void +GetNormalGC(LabelWidget lw) +{ + XGCValues values; + + values.foreground = lw->label.foreground; + values.background = lw->core.background_pixel; + values.font = lw->label.font->fid; + values.graphics_exposures = False; + + if (lw->simple.international == True) + /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC */ + lw->label.normal_GC = XtAllocateGC((Widget)lw, 0, + GCForeground | GCBackground | + GCGraphicsExposures, + &values, GCFont, 0); + else + lw->label.normal_GC = XtGetGC((Widget)lw, + GCForeground | GCBackground | GCFont | + GCGraphicsExposures, &values); +} + +static void +GetGrayGC(LabelWidget lw) +{ + XGCValues values; + + values.foreground = lw->label.foreground; + values.background = lw->core.background_pixel; + values.font = lw->label.font->fid; + values.fill_style = FillTiled; + values.tile = XmuCreateStippledPixmap(XtScreen((Widget)lw), + lw->label.foreground, + lw->core.background_pixel, + lw->core.depth); + values.graphics_exposures = False; + + lw->label.stipple = values.tile; + if (lw->simple.international == True) + /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC */ + lw->label.gray_GC = XtAllocateGC((Widget)lw, 0, + GCForeground | GCBackground | + GCTile | GCFillStyle | + GCGraphicsExposures, + &values, GCFont, 0); + else + lw->label.gray_GC = XtGetGC((Widget)lw, + GCForeground | GCBackground | + GCFont | GCTile | GCFillStyle | + GCGraphicsExposures, + &values); +} + +static void +compute_bitmap_offsets(LabelWidget lw) +{ + /* + * bitmap will be eventually be displayed at + * (internal_width, internal_height + lbm_y) + */ + if (lw->label.lbm_height != 0) + lw->label.lbm_y = (XtHeight(lw) - (lw->label.internal_height * 2 + + lw->label.lbm_height)) / 2; + else + lw->label.lbm_y = 0; +} + +static void +set_bitmap_info(LabelWidget lw) +{ + Window root; + int x, y; + unsigned int bw, depth; + + if (!(lw->label.left_bitmap + && XGetGeometry(XtDisplay(lw), lw->label.left_bitmap, &root, &x, &y, + &lw->label.lbm_width, &lw->label.lbm_height, + &bw, &depth))) + lw->label.lbm_width = lw->label.lbm_height = 0; + + compute_bitmap_offsets(lw); +} + +/*ARGSUSED*/ +static void +XawLabelInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + LabelWidget lw = (LabelWidget)cnew; + + if (!lw->label.font) XtError("Aborting: no font found\n"); + if (lw->simple.international && !lw->label.fontset) + XtError("Aborting: no fontset found\n"); + + if (lw->label.label == NULL) + lw->label.label = XtNewString(lw->core.name); + else + lw->label.label = XtNewString(lw->label.label); + + GetNormalGC(lw); + GetGrayGC(lw); + + SetTextWidthAndHeight(lw); + + if (XtHeight(lw) == 0) + XtHeight(lw) = lw->label.label_height + 2 * lw->label.internal_height; + + set_bitmap_info(lw); /* need core.height */ + + if (XtWidth(lw) == 0) /* need label.lbm_width */ + XtWidth(lw) = lw->label.label_width + 2 * lw->label.internal_width + + LEFT_OFFSET(lw); + + lw->label.label_x = lw->label.label_y = 0; + (*XtClass(cnew)->core_class.resize)((Widget)lw); +} + +/*ARGSUSED*/ +static void +XawLabelRedisplay(Widget gw, XEvent *event, Region region) +{ + LabelWidget w = (LabelWidget)gw; + GC gc; + + if (*Superclass->core_class.expose != NULL) + (*Superclass->core_class.expose)(gw, event, region); + + gc = XtIsSensitive(gw) ? w->label.normal_GC : w->label.gray_GC; +#ifdef notdef + if (region != NULL) + XSetRegion(XtDisplay(gw), gc, region); +#endif /*notdef*/ + + if (w->label.pixmap == None) { + int len = w->label.label_len; + char *label = w->label.label; + Position y = w->label.label_y + w->label.font->max_bounds.ascent; + Position ksy = w->label.label_y; + + /* display left bitmap */ + if (w->label.left_bitmap && w->label.lbm_width != 0) + XCopyPlane (XtDisplay(gw), w->label.left_bitmap, XtWindow(gw), gc, + 0, 0, w->label.lbm_width, w->label.lbm_height, + w->label.internal_width, + w->label.internal_height + w->label.lbm_y, 1L); + + if (w->simple.international == True) { + XFontSetExtents *ext = XExtentsOfFontSet(w->label.fontset); + + ksy += XawAbs(ext->max_ink_extent.y); + + if (len == MULTI_LINE_LABEL) { + char *nl; + + while ((nl = index(label, '\n')) != NULL) { + XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, + gc, w->label.label_x, ksy, label, + (int)(nl - label)); + ksy += ext->max_ink_extent.height; + label = nl + 1; + } + len = strlen(label); + } + if (len) + XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, + w->label.label_x, ksy, label, len); + } + else { + if (len == MULTI_LINE_LABEL) { + char *nl; + + while ((nl = index(label, '\n')) != NULL) { + if (w->label.encoding) + XDrawString16(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, + (TXT16*)label, (int)(nl - label) / 2); + else + XDrawString(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, label, (int)(nl - label)); + y += w->label.font->max_bounds.ascent + + w->label.font->max_bounds.descent; + label = nl + 1; + } + len = strlen(label); + } + if (len) { + if (w->label.encoding) + XDrawString16(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, (TXT16*)label, len / 2); + else + XDrawString(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, label, len); + } + } + } + else if (w->label.label_len == 1) + XCopyPlane(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, + 0, 0, w->label.label_width, w->label.label_height, + w->label.label_x, w->label.label_y, 1L); + else + XCopyArea(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, + 0, 0, w->label.label_width, w->label.label_height, + w->label.label_x, w->label.label_y); + +#ifdef notdef + if (region != NULL) + XSetClipMask(XtDisplay(gw), gc, (Pixmap)None); +#endif /* notdef */ +} + +static void +_Reposition(LabelWidget lw, unsigned int width, unsigned int height, + Position *dx, Position *dy) +{ + Position newPos; + Position leftedge = lw->label.internal_width + LEFT_OFFSET(lw); + + switch (lw->label.justify) { + case XtJustifyLeft: + newPos = leftedge; + break; + case XtJustifyRight: + newPos = width - (lw->label.label_width + lw->label.internal_width); + break; + case XtJustifyCenter: + /*FALLTRHOUGH*/ + default: + newPos = (int)(width - lw->label.label_width) >> 1; + break; + } + if (newPos < (Position)leftedge) + newPos = leftedge; + *dx = newPos - lw->label.label_x; + lw->label.label_x = newPos; + + newPos = (height - lw->label.label_height) >> 1; + *dy = newPos - lw->label.label_y; + lw->label.label_y = newPos; +} + +static void +XawLabelResize(Widget w) +{ + LabelWidget lw = (LabelWidget)w; + Position dx, dy; + + _Reposition(lw, XtWidth(w), XtHeight(w), &dx, &dy); + compute_bitmap_offsets(lw); +} + +#define PIXMAP 0 +#define WIDTH 1 +#define HEIGHT 2 +#define NUM_CHECKS 3 +static Boolean +XawLabelSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + LabelWidget curlw = (LabelWidget)current; + LabelWidget reqlw = (LabelWidget)request; + LabelWidget newlw = (LabelWidget)cnew; + unsigned int i; + Boolean was_resized = False, redisplay = False, checks[NUM_CHECKS]; + + for (i = 0; i < NUM_CHECKS; i++) + checks[i] = False; + + for (i = 0; i < *num_args; i++) { + if (streq(XtNbitmap, args[i].name)) + checks[PIXMAP] = True; + else if (streq(XtNwidth, args[i].name)) + checks[WIDTH] = True; + else if (streq(XtNheight, args[i].name)) + checks[HEIGHT] = True; + } + + if (newlw->label.label == NULL) + newlw->label.label = newlw->core.name; + + /* + * resize on bitmap change + */ + if (curlw->label.left_bitmap != newlw->label.left_bitmap) + was_resized = True; + + if (curlw->label.encoding != newlw->label.encoding) + was_resized = True; + + if (curlw->simple.international + && curlw->label.fontset != newlw->label.fontset) + was_resized = True; + + if (curlw->label.label != newlw->label.label) { + if (curlw->label.label != curlw->core.name) + XtFree((char *)curlw->label.label); + + if (newlw->label.label != newlw->core.name) + newlw->label.label = XtNewString(newlw->label.label); + + was_resized = True; + } + + if (was_resized || (curlw->label.font != newlw->label.font) || + curlw->label.justify != newlw->label.justify || checks[PIXMAP]) { + SetTextWidthAndHeight(newlw); + was_resized = True; + } + + /* recalculate the window size if something has changed */ + if (newlw->label.resize && was_resized) { + if (XtHeight(curlw) == XtHeight(reqlw) && !checks[HEIGHT]) + XtHeight(newlw) = newlw->label.label_height + + (newlw->label.internal_height << 1); + + set_bitmap_info(newlw); + + if (XtWidth(curlw) == XtWidth(reqlw) && !checks[WIDTH]) + XtWidth(newlw) = newlw->label.label_width + LEFT_OFFSET(newlw) + + (newlw->label.internal_width << 1); + } + + if (curlw->label.foreground != newlw->label.foreground + || curlw->core.background_pixel != newlw->core.background_pixel + || curlw->label.font->fid != newlw->label.font->fid) { + /* The Fontset is not in the GC - don't make a new GC if FS changes! */ + XtReleaseGC(cnew, curlw->label.normal_GC); + XtReleaseGC(cnew, curlw->label.gray_GC); + XmuReleaseStippledPixmap(XtScreen(current), curlw->label.stipple); + GetNormalGC(newlw); + GetGrayGC(newlw); + redisplay = True; + } + + if (curlw->label.label_x != newlw->label.label_x || + curlw->label.label_y != newlw->label.label_y) + redisplay = True; + + if (curlw->label.internal_width != newlw->label.internal_width + || curlw->label.internal_height != newlw->label.internal_height + || was_resized) { + /* Resize() will be called if geometry changes succeed */ + Position dx, dy; + + _Reposition(newlw, XtWidth(curlw), XtHeight(curlw), &dx, &dy); + } + + return (was_resized || redisplay || + XtIsSensitive(current) != XtIsSensitive(cnew)); +} + +static void +XawLabelDestroy(Widget w) +{ + LabelWidget lw = (LabelWidget)w; + + if (lw->label.label != lw->core.name) + XtFree(lw->label.label); + XtReleaseGC(w, lw->label.normal_GC); + XtReleaseGC(w, lw->label.gray_GC); + XmuReleaseStippledPixmap(XtScreen(w), lw->label.stipple); +} + +static XtGeometryResult +XawLabelQueryGeometry(Widget w, XtWidgetGeometry *intended, + XtWidgetGeometry *preferred) +{ + LabelWidget lw = (LabelWidget)w; + + preferred->request_mode = CWWidth | CWHeight; + preferred->width = lw->label.label_width + + (lw->label.internal_width << 1) + LEFT_OFFSET(lw); + preferred->height = lw->label.label_height + + (lw->label.internal_height << 1); + + if (((intended->request_mode & (CWWidth | CWHeight)) == (CWWidth | CWHeight)) + && intended->width == preferred->width + && intended->height == preferred->height) + return (XtGeometryYes); + else if (preferred->width == XtWidth(w) && preferred->height == XtHeight(w)) + return (XtGeometryNo); + + return (XtGeometryAlmost); +} diff --git a/src/List.c b/src/List.c new file mode 100644 index 0000000..ce0ab5f --- /dev/null +++ b/src/List.c @@ -0,0 +1,1270 @@ +/* +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +/* + * List.c - List widget + * + * This is a List widget. It allows the user to select an item in a list and + * notifies the application through a callback function. + * + * Created: 8/13/88 + * By: Chris D. Peterson + * MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#define HeightLock 1 +#define WidthLock 2 +#define LongestLock 4 + +#define HeightFree(w) !(((ListWidget)(w))->list.freedoms & HeightLock) +#define WidthFree(w) !(((ListWidget)(w))->list.freedoms & WidthLock) +#define LongestFree(w) !(((ListWidget)(w))->list.freedoms & LongestLock) + +#define MaxSize 32767 + +/* + * Class Methods + */ +static void XawListDestroy(Widget); +static void XawListInitialize(Widget, Widget, ArgList, Cardinal*); +static XtGeometryResult XawListQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawListRedisplay(Widget, XEvent*, Region); +static void XawListResize(Widget); +static Boolean XawListSetValues(Widget, Widget, Widget, ArgList, Cardinal*); + +/* + * Prototypes + */ +static void CalculatedValues(Widget); +static void ChangeSize(Widget, unsigned int, unsigned int); +static void ClipToShadowInteriorAndLongest(ListWidget, GC*, unsigned int); +static int CvtToItem(Widget, int, int, int*); +static void FindCornerItems(Widget, XEvent*, int*, int*); +static void GetGCs(Widget); +static void HighlightBackground(Widget, int, int, GC); +static Bool ItemInRectangle(Widget, int, int, int); +static Bool Layout(Widget, Bool, Bool, Dimension*, Dimension*); +static void PaintItemName(Widget, int); +static void ResetList(Widget, Bool, Bool); + +/* + * Actions + */ +static void Notify(Widget, XEvent*, String*, Cardinal*); +static void Set(Widget, XEvent*, String*, Cardinal*); +static void Unset(Widget, XEvent*, String*, Cardinal*); + +/* + * Initialization + */ +static char defaultTranslations[] = +":" "Set()\n" +":" "Notify()\n" +; + +#define offset(field) XtOffsetOf(ListRec, field) +static XtResource resources[] = { + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(list.foreground), + XtRString, + XtDefaultForeground + }, + { + XtNcursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(simple.cursor), + XtRString, + "left_ptr" + }, + { + XtNfont, + XtCFont, + XtRFontStruct, + sizeof(XFontStruct*), + offset(list.font), + XtRString, + XtDefaultFont + }, + { + XtNfontSet, + XtCFontSet, + XtRFontSet, + sizeof(XFontSet), + offset(list.fontset), + XtRString, + XtDefaultFontSet + }, + { + XtNlist, + XtCList, + XtRPointer, + sizeof(char**), + offset(list.list), +#ifdef notyet + XtRStringArray, +#else + XtRString, +#endif + NULL + }, + { + XtNdefaultColumns, + XtCColumns, + XtRInt, + sizeof(int), + offset(list.default_cols), + XtRImmediate, + (XtPointer)2 + }, + { + XtNlongest, + XtCLongest, + XtRInt, + sizeof(int), + offset(list.longest), + XtRImmediate, + (XtPointer)0 + }, + { + XtNnumberStrings, + XtCNumberStrings, + XtRInt, + sizeof(int), + offset(list.nitems), + XtRImmediate, + (XtPointer)0 + }, + { + XtNpasteBuffer, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(list.paste), + XtRImmediate, + (XtPointer)False + }, + { + XtNforceColumns, + XtCColumns, + XtRBoolean, + sizeof(Boolean), + offset(list.force_cols), + XtRImmediate, + (XtPointer)False + }, + { + XtNverticalList, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(list.vertical_cols), + XtRImmediate, + (XtPointer)False + }, + { + XtNinternalWidth, + XtCWidth, + XtRDimension, + sizeof(Dimension), + offset(list.internal_width), + XtRImmediate, + (XtPointer)2 + }, + { + XtNinternalHeight, + XtCHeight, + XtRDimension, + sizeof(Dimension), + offset(list.internal_height), + XtRImmediate, + (XtPointer)2 + }, + { + XtNcolumnSpacing, + XtCSpacing, + XtRDimension, + sizeof(Dimension), + offset(list.column_space), + XtRImmediate, + (XtPointer)6 + }, + { + XtNrowSpacing, + XtCSpacing, + XtRDimension, + sizeof(Dimension), + offset(list.row_space), + XtRImmediate, + (XtPointer)2 + }, + { + XtNcallback, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + offset(list.callback), + XtRCallback, + NULL + }, +#ifndef OLDXAW + { + XtNshowCurrent, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(list.show_current), + XtRImmediate, + (XtPointer)False + }, +#endif +}; +#undef offset + +static XtActionsRec actions[] = { + {"Notify", Notify}, + {"Set", Set}, + {"Unset", Unset}, +}; + +#define Superclass (&simpleClassRec) +ListClassRec listClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "List", /* class_name */ + sizeof(ListRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawListInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + actions, /* actions */ + XtNumber(actions), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + False, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawListDestroy, /* destroy */ + XawListResize, /* resize */ + XawListRedisplay, /* expose */ + XawListSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + defaultTranslations, /* tm_table */ + XawListQueryGeometry, /* query_geometry */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* list */ + { + NULL, /* extension */ + }, +}; + +WidgetClass listWidgetClass = (WidgetClass)&listClassRec; + +/* + * Implementation + */ +static void +GetGCs(Widget w) +{ + XGCValues values; + ListWidget lw = (ListWidget)w; + + values.foreground = lw->list.foreground; + values.font = lw->list.font->fid; + + if (lw->simple.international == True) + lw->list.normgc = XtAllocateGC(w, 0, GCForeground, &values, GCFont, 0); + else + lw->list.normgc = XtGetGC(w, GCForeground | GCFont, &values); + + values.foreground = lw->core.background_pixel; + + if (lw->simple.international == True) + lw->list.revgc = XtAllocateGC(w, 0, GCForeground, &values, GCFont, 0); + else + lw->list.revgc = XtGetGC(w, GCForeground | GCFont, &values); + + values.tile = XmuCreateStippledPixmap(XtScreen(w), + lw->list.foreground, + lw->core.background_pixel, + lw->core.depth); + values.fill_style = FillTiled; + + if (lw->simple.international == True) + lw->list.graygc = XtAllocateGC(w, 0, GCTile | GCFillStyle, + &values, GCFont, 0); + else + lw->list.graygc = XtGetGC(w, GCFont | GCTile | GCFillStyle, &values); +} + +static void +CalculatedValues(Widget w) +{ + int i, len; + ListWidget lw = (ListWidget)w; + + /* If list is NULL then the list will just be the name of the widget */ + if (lw->list.list == NULL) { + lw->list.list = &lw->core.name; + lw->list.nitems = 1; + } + + /* Get number of items */ + if (lw->list.nitems == 0) + for (; lw->list.list[lw->list.nitems] != NULL ; lw->list.nitems++) + ; + + /* Get column width */ + if (LongestFree(lw)) { + lw->list.longest = 0; /* so it will accumulate real longest below */ + + for (i = 0 ; i < lw->list.nitems; i++) { + if (lw->simple.international == True) + len = XmbTextEscapement(lw->list.fontset, lw->list.list[i], + strlen(lw->list.list[i])); + else + len = XTextWidth(lw->list.font, lw->list.list[i], + strlen(lw->list.list[i])); + if (len > lw->list.longest) + lw->list.longest = len; + } + } + + lw->list.col_width = lw->list.longest + lw->list.column_space; +} + +/* + * Function: + * ResetList + * + * Parameters: + * w - list widget + * changex - allow the height or width to change? + * changey - "" + * + * Description: + * Resets the new list when important things change. + * + * Returns: + * True if width or height have been changed + */ +static void +ResetList(Widget w, Bool changex, Bool changey) +{ + Dimension width = XtWidth(w); + Dimension height = XtHeight(w); + + CalculatedValues(w); + + if (Layout(w, changex, changey, &width, &height)) { + if (XtIsComposite(XtParent(w))) + ChangeSize(w, width, height); + else { + XtWidth(w) = width; + XtHeight(w) = height; + } + } +} + +/* + * Function: + * ChangeSize + * + * Parameters: + * w - widget to try change the size of + * + * Description: + * Laysout the widget. + */ +static void +ChangeSize(Widget w, unsigned int width, unsigned int height) +{ + XtWidgetGeometry request, reply; + + request.request_mode = CWWidth | CWHeight; + request.width = width; + request.height = height; + + switch (XtMakeGeometryRequest(w, &request, &reply)) { + case XtGeometryYes: + case XtGeometryNo: + break; + case XtGeometryAlmost: + Layout(w, request.height != reply.height, + request.width != reply.width, &reply.width, &reply.height); + request = reply; + switch (XtMakeGeometryRequest(w, &request, &reply)) { + case XtGeometryYes: + case XtGeometryNo: + break; + case XtGeometryAlmost: + request = reply; + Layout(w, False, False, &request.width, &request.height); + request.request_mode = CWWidth | CWHeight; + XtMakeGeometryRequest(w, &request, &reply); + /*FALLTROUGH*/ + default: + break; + } + /*FALLTROUGH*/ + default: + break; + } +} + +/*ARGSUSED*/ +static void +XawListInitialize(Widget temp1, Widget cnew, ArgList args, Cardinal *num_args) +{ + ListWidget lw = (ListWidget)cnew; + + if (!lw->list.font) XtError("Aborting: no font found\n"); + if (lw->simple.international && !lw->list.fontset) + XtError("Aborting: no fontset found\n"); + + /* + * Initialize all private resources + */ + /* record for posterity if we are free */ + lw->list.freedoms = ((XtWidth(lw) != 0) * WidthLock + + (XtHeight(lw) != 0) * HeightLock + + (lw->list.longest != 0) * LongestLock); + + GetGCs(cnew); + + /* Set row height, based on font or fontset */ + if (lw->simple.international == True) + lw->list.row_height = + XExtentsOfFontSet(lw->list.fontset)->max_ink_extent.height + + lw->list.row_space; + else + lw->list.row_height = lw->list.font->max_bounds.ascent + + lw->list.font->max_bounds.descent + + lw->list.row_space; + + ResetList(cnew, WidthFree(lw), HeightFree(lw)); + + lw->list.highlight = lw->list.is_highlighted = NO_HIGHLIGHT; +} + +/* + * Function: + * CvtToItem + * + * Parameters: + * w - list widget + * xloc - x location + * yloc - y location + * + * Description: + * Converts Xcoord to item number of item containing that point. + * + * Returns: + * Item number + */ +static int +CvtToItem(Widget w, int xloc, int yloc, int *item) +{ + int one, another; + ListWidget lw = (ListWidget)w; + int ret_val = OKAY; + + if (lw->list.vertical_cols) { + one = lw->list.nrows * ((xloc - (int)lw->list.internal_width) + / lw->list.col_width); + another = (yloc - (int)lw->list.internal_height) / lw->list.row_height; + /* If out of range, return minimum possible value */ + if (another >= lw->list.nrows) { + another = lw->list.nrows - 1; + ret_val = OUT_OF_RANGE; + } + } + else { + one = (lw->list.ncols * ((yloc - (int)lw->list.internal_height) + / lw->list.row_height)); + /* If in right margin handle things right */ + another = (xloc - (int)lw->list.internal_width) / lw->list.col_width; + if (another >= lw->list.ncols) { + another = lw->list.ncols - 1; + ret_val = OUT_OF_RANGE; + } + } + if (xloc < 0 || yloc < 0) + ret_val = OUT_OF_RANGE; + if (one < 0) + one = 0; + if (another < 0) + another = 0; + *item = one + another; + if (*item >= lw->list.nitems) + return (OUT_OF_RANGE); + + return (ret_val); +} + +/* + * Function: + * FindCornerItems + * + * Arguments: + * w - list widget + * event - event structure that has the rectangle it it + * ul_ret - the corners (return) + * lr_ret - "" + * + * Description: + * Find the corners of the rectangle in item space. + */ +static void +FindCornerItems(Widget w, XEvent *event, int *ul_ret, int *lr_ret) +{ + int xloc, yloc; + + xloc = event->xexpose.x; + yloc = event->xexpose.y; + CvtToItem(w, xloc, yloc, ul_ret); + xloc += event->xexpose.width; + yloc += event->xexpose.height; + CvtToItem(w, xloc, yloc, lr_ret); +} + +/* + * Function: + * ItemInRectangle + * + * Parameters: + * w - list widget + * ul - corners of the rectangle in item space + * lr - "" + * item - item to check + * + * Returns: + * True if the item passed is in the given rectangle + */ +static Bool +ItemInRectangle(Widget w, int ul, int lr, int item) +{ + ListWidget lw = (ListWidget)w; + int mod_item; + int things; + + if (item < ul || item > lr) + return (False); + if (lw->list.vertical_cols) + things = lw->list.nrows; + else + things = lw->list.ncols; + + mod_item = item % things; + if ((mod_item >= ul % things) && (mod_item <= lr % things)) + return (True); + + return (False); +} + +/* HighlightBackground() + * + * Paints the color of the background for the given item. It performs + * clipping to the interior of internal_width/height by hand, as its a + * simple calculation and probably much faster than using Xlib and a clip mask. + * + * x, y - ul corner of the area item occupies. + * gc - the gc to use to paint this rectangle + */ +static void +HighlightBackground(Widget w, int x, int y, GC gc) +{ + ListWidget lw = (ListWidget)w; + Dimension width = lw->list.col_width; + Dimension height = lw->list.row_height; + Dimension frame_limited_width = XtWidth(w) - lw->list.internal_width - x; + Dimension frame_limited_height= XtHeight(w) - lw->list.internal_height - y; + + /* Clip the rectangle width and height to the edge of the drawable area */ + if (width > frame_limited_width) + width = frame_limited_width; + if (height > frame_limited_height) + height = frame_limited_height; + + /* Clip the rectangle x and y to the edge of the drawable area */ + if (x < lw->list.internal_width) { + width = width - (lw->list.internal_width - x); + x = lw->list.internal_width; + } + if (y < lw->list.internal_height) { + height = height - (lw->list.internal_height - y); + y = lw->list.internal_height; + } + + if (gc == lw->list.revgc && lw->core.background_pixmap != XtUnspecifiedPixmap) + XClearArea(XtDisplay(w), XtWindow(w), x, y, width, height, False); + else + XFillRectangle(XtDisplay(w), XtWindow(w), gc, x, y, width, height); +} + + +/* ClipToShadowInteriorAndLongest() + * + * Converts the passed gc so that any drawing done with that GC will not + * write in the empty margin (specified by internal_width/height) (which also + * prevents erasing the shadow. It also clips against the value longest. + * If the user doesn't set longest, this has no effect (as longest is the + * maximum of all item lengths). If the user does specify, say, 80 pixel + * columns, though, this prevents items from overwriting other items. + */ +static void +ClipToShadowInteriorAndLongest(ListWidget lw, GC *gc_p, unsigned int x) +{ + XRectangle rect; + + rect.x = x; + rect.y = lw->list.internal_height; + rect.height = XtHeight(lw) - (lw->list.internal_height << 1); + rect.width = XtWidth(lw) - lw->list.internal_width - x; + if (rect.width > lw->list.longest) + rect.width = lw->list.longest; + + XSetClipRectangles(XtDisplay((Widget)lw), *gc_p, 0, 0, &rect, 1, YXBanded); +} + +static void +PaintItemName(Widget w, int item) +{ + char *str; + GC gc; + int x, y, str_y; + ListWidget lw = (ListWidget)w; + XFontSetExtents *ext = XExtentsOfFontSet(lw->list.fontset); + + if (!XtIsRealized(w) || item > lw->list.nitems) + return; + + if (lw->list.vertical_cols) { + x = lw->list.col_width * (item / lw->list.nrows) + + lw->list.internal_width; + y = lw->list.row_height * (item % lw->list.nrows) + + lw->list.internal_height; + } + else { + x = lw->list.col_width * (item % lw->list.ncols) + + lw->list.internal_width; + y = lw->list.row_height * (item / lw->list.ncols) + + lw->list.internal_height; + } + + if ( lw->simple.international == True ) + str_y = y + XawAbs(ext->max_ink_extent.y); + else + str_y = y + lw->list.font->max_bounds.ascent; + + if (item == lw->list.is_highlighted) { + if (item == lw->list.highlight) { + gc = lw->list.revgc; + HighlightBackground(w, x, y, lw->list.normgc); + } + else { + if (XtIsSensitive(w)) + gc = lw->list.normgc; + else + gc = lw->list.graygc; + HighlightBackground(w, x, y, lw->list.revgc); + lw->list.is_highlighted = NO_HIGHLIGHT; + } + } + else { + if (item == lw->list.highlight) { + gc = lw->list.revgc; + HighlightBackground(w, x, y, lw->list.normgc); + lw->list.is_highlighted = item; + } + else { + if (XtIsSensitive(w)) + gc = lw->list.normgc; + else + gc = lw->list.graygc; + } + } + + /* List's overall width contains the same number of inter-column + column_space's as columns. There should thus be a half + column_width margin on each side of each column. + The row case is symmetric */ + + x += lw->list.column_space >> 1; + str_y += lw->list.row_space >> 1; + + str = lw->list.list[item]; /* draw it */ + + ClipToShadowInteriorAndLongest(lw, &gc, x); + + if (lw->simple.international == True) + XmbDrawString(XtDisplay(w), XtWindow(w), lw->list.fontset, + gc, x, str_y, str, strlen(str)); + else + XDrawString(XtDisplay(w), XtWindow(w), gc, x, str_y, str, strlen(str)); + + XSetClipMask(XtDisplay(w), gc, None); +} + +static void +XawListRedisplay(Widget w, XEvent *event, Region region) +{ + int item; /* an item to work with */ + int ul_item, lr_item; /* corners of items we need to paint */ + ListWidget lw = (ListWidget)w; + + if (event == NULL) { + ul_item = 0; + lr_item = lw->list.nrows * lw->list.ncols - 1; + XClearWindow(XtDisplay(w), XtWindow(w)); + } + else + FindCornerItems(w, event, &ul_item, &lr_item); + + if (Superclass->core_class.expose) + (Superclass->core_class.expose)(w, event, region); + + for (item = ul_item; item <= lr_item && item < lw->list.nitems; item++) + if (ItemInRectangle(w, ul_item, lr_item, item)) + PaintItemName(w, item); +} + +/* XawListQueryGeometry() + * + * This tells the parent what size we would like to be + * given certain constraints. + * w - the widget. + * intended - what the parent intends to do with us. + * requested - what we want to happen */ +static XtGeometryResult +XawListQueryGeometry(Widget w, XtWidgetGeometry *intended, + XtWidgetGeometry *requested) +{ + Dimension new_width, new_height; + Bool change, width_req, height_req; + + width_req = intended->request_mode & CWWidth; + height_req = intended->request_mode & CWHeight; + + if (width_req) + new_width = intended->width; + else + new_width = XtWidth(w); + + if (height_req) + new_height = intended->height; + else + new_height = XtHeight(w); + + requested->request_mode = 0; + + /* + * We only care about our height and width + */ + if (!width_req && !height_req) + return (XtGeometryYes); + + change = Layout(w, !width_req, !height_req, &new_width, &new_height); + + requested->request_mode |= CWWidth; + requested->width = new_width; + requested->request_mode |= CWHeight; + requested->height = new_height; + + if (change) + return (XtGeometryAlmost); + + return (XtGeometryYes); +} + +static void +XawListResize(Widget w) +{ + Dimension width, height; + + width = XtWidth(w); + height = XtHeight(w); + + if (Layout(w, False, False, &width, &height)) + XtAppWarning(XtWidgetToApplicationContext(w), + "List Widget: Size changed when it shouldn't " + "have when resising."); +} + +/* Layout() + * + * lays out the item in the list. + * w - the widget. + * xfree, yfree - True if we are free to resize the widget in + * this direction. + * width, height- the is the current width and height that we are going + * we are going to layout the list widget to, + * depending on xfree and yfree of course. + * + * Return: + * True if width or height have been changed */ +static Bool +Layout(Widget w, Bool xfree, Bool yfree, Dimension *width, Dimension *height) +{ + ListWidget lw = (ListWidget)w; + Bool change = False; + unsigned long width2 = 0, height2 = 0; + + /* + * If force columns is set then always use number of columns specified + * by default_cols + */ + if (lw->list.force_cols) { + lw->list.ncols = lw->list.default_cols; + if (lw->list.ncols <= 0) + lw->list.ncols = 1; + lw->list.nrows = ((lw->list.nitems - 1) / lw->list.ncols) + 1; + if (xfree) { + /* this counts the same number + of inter-column column_space 's as columns. There should thus + be a half column_space margin on each side of each column...*/ + width2 = lw->list.ncols * lw->list.col_width + + (lw->list.internal_width << 1); + change = True; + } + if (yfree) { + height2 = lw->list.nrows * lw->list.row_height + + (lw->list.internal_height << 1); + change = True; + } + } + + /* + * If both width and height are free to change the use default_cols + * to determine the number columns and set new width and height to + * just fit the window + */ + else if (xfree && yfree) { + lw->list.ncols = lw->list.default_cols; + if (lw->list.ncols <= 0) { + int wid = (int)XtWidth(lw) - (int)(lw->list.internal_width << 1) + + (int)lw->list.column_space; + + if (wid <= 0 || lw->list.col_width <= 0 + || (lw->list.ncols = wid / lw->list.col_width) <= 0) + lw->list.ncols = 1; + } + width2 = lw->list.ncols * lw->list.col_width + + (lw->list.internal_width << 1); + height2 = (lw->list.nrows * lw->list.row_height) + + (lw->list.internal_height << 1); + change = True; + } + + /* + * If the width is fixed then use it to determine the number of columns. + * If the height is free to move (width still fixed) then resize the height + * of the widget to fit the current list exactly + */ + else if (!xfree) { + lw->list.ncols = ((int)(*width - (lw->list.internal_width << 1)) + / (int)lw->list.col_width); + if (lw->list.ncols <= 0) + lw->list.ncols = 1; + lw->list.nrows = ((lw->list.nitems - 1) / lw->list.ncols) + 1; + if (yfree) { + height2 = lw->list.nrows * lw->list.row_height + + (lw->list.internal_height << 1); + change = True; + } + } + + /* + * The last case is xfree and !yfree we use the height to determine + * the number of rows and then set the width to just fit the resulting + * number of columns + */ + else if (!yfree) { + lw->list.nrows = ((int)(*height - (lw->list.internal_height << 1)) + / (int)lw->list.row_height); + if (lw->list.nrows <= 0) + lw->list.nrows = 1; + lw->list.ncols = ((lw->list.nitems - 1) / lw->list.nrows) + 1; + width2 = lw->list.ncols * lw->list.col_width + + (lw->list.internal_width << 1); + change = True; + } + + if (!lw->list.force_cols && lw->list.nrows) { + /*CONSTCOND*/ + while (1) { + lw->list.nrows = ((lw->list.nitems - 1) / lw->list.ncols) + 1; + width2 = lw->list.ncols * lw->list.col_width + + (lw->list.internal_width << 1); + height2 = lw->list.nrows * lw->list.row_height + + (lw->list.internal_height << 1); + if (width2 >= MaxSize && height2 >= MaxSize) + break; + if (height2 > MaxSize) + ++lw->list.ncols; + else if (width2 > MaxSize && lw->list.ncols > 1) + --lw->list.ncols; + else + break; + } + } + if (width2) + *width = width2; + if (height2) + *height = height2; + + return (change); +} + +/* Notify() - Action + * + * Notifies the user that a button has been pressed, and + * calls the callback; if the XtNpasteBuffer resource is true + * then the name of the item is also put in CUT_BUFFER0 */ +/*ARGSUSED*/ +static void +Notify(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + ListWidget lw = (ListWidget)w; + int item, item_len; + XawListReturnStruct ret_value; + + /* + * Find item and if out of range then unhighlight and return + * + * If the current item is unhighlighted then the user has aborted the + * notify, so unhighlight and return + */ + if ((CvtToItem(w, event->xbutton.x, event->xbutton.y, &item) == OUT_OF_RANGE) + || lw->list.highlight != item) { +#ifndef OLDXAW + if (!lw->list.show_current || lw->list.selected == NO_HIGHLIGHT) + XawListUnhighlight(w); + else + XawListHighlight(w, lw->list.selected); +#else + XawListUnhighlight(w); +#endif + return; + } + + item_len = strlen(lw->list.list[item]); + + if (lw->list.paste) /* if XtNpasteBuffer set then paste it */ + XStoreBytes(XtDisplay(w), lw->list.list[item], item_len); + +#ifndef OLDXAW + lw->list.selected = item; +#endif + /* + * Call Callback function + */ + ret_value.string = lw->list.list[item]; + ret_value.list_index = item; + + XtCallCallbacks(w, XtNcallback, (XtPointer)&ret_value); +} + +/* Unset() - Action + * + * unhighlights the current element */ +/*ARGSUSED*/ +static void +Unset(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + XawListUnhighlight(w); +} + +/* Set() - Action + * + * Highlights the current element */ +/*ARGSUSED*/ +static void +Set(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + int item; + ListWidget lw = (ListWidget)w; + +#ifndef OLDXAW + lw->list.selected = lw->list.highlight; +#endif + if (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item) == OUT_OF_RANGE) + XawListUnhighlight(w); /* Unhighlight current item */ + else if (lw->list.is_highlighted != item) /* If this item is not */ + XawListHighlight(w, item); /* highlighted then do it */ +} + +/* + * Set specified arguments into widget + */ +/*ARGSUSED*/ +static Boolean +XawListSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + ListWidget cl = (ListWidget)current; + ListWidget rl = (ListWidget)request; + ListWidget nl = (ListWidget)cnew; + Bool redraw = False; + XFontSetExtents *ext = XExtentsOfFontSet(nl->list.fontset); + + /* If the request height/width is different, lock it. Unless its 0. If + neither new nor 0, leave it as it was. Not in R5 */ + if (XtWidth(nl) != XtWidth(cl)) + nl->list.freedoms |= WidthLock; + if (XtWidth(nl) == 0) + nl->list.freedoms &= ~WidthLock; + + if (XtHeight(nl) != XtHeight(cl)) + nl->list.freedoms |= HeightLock; + if (XtHeight(nl) == 0) + nl->list.freedoms &= ~HeightLock; + + if (nl->list.longest != cl->list.longest) + nl->list.freedoms |= LongestLock; + if (nl->list.longest == 0) + nl->list.freedoms &= ~LongestLock; + + if (cl->list.foreground != nl->list.foreground || + cl->core.background_pixel != nl->core.background_pixel || + cl->list.font != nl->list.font) { + XGCValues values; + + XGetGCValues(XtDisplay(current), cl->list.graygc, GCTile, &values); + XmuReleaseStippledPixmap(XtScreen(current), values.tile); + XtReleaseGC(current, cl->list.graygc); + XtReleaseGC(current, cl->list.revgc); + XtReleaseGC(current, cl->list.normgc); + GetGCs(cnew); + redraw = True; + } + + if (cl->list.font != nl->list.font && cl->simple.international == False) + nl->list.row_height = nl->list.font->max_bounds.ascent + + nl->list.font->max_bounds.descent + + nl->list.row_space; + else if (cl->list.fontset != nl->list.fontset + && cl->simple.international == True) + nl->list.row_height = ext->max_ink_extent.height + nl->list.row_space; + + /* ...If the above two font(set) change checkers above both failed, check + if row_space was altered. If one of the above passed, row_height will + already have been re-calculated */ + else if (cl->list.row_space != nl->list.row_space) { + if (cl->simple.international == True) + nl->list.row_height = ext->max_ink_extent.height + nl->list.row_space; + else + nl->list.row_height = nl->list.font->max_bounds.ascent + + nl->list.font->max_bounds.descent + + nl->list.row_space; + } + + if (XtWidth(cl) != XtWidth(nl) || XtHeight(cl) != XtHeight(nl) + || cl->list.internal_width != nl->list.internal_width + || cl->list.internal_height != nl->list.internal_height + || cl->list.column_space != nl->list.column_space + || cl->list.row_space != nl->list.row_space + || cl->list.default_cols != nl->list.default_cols + || (cl->list.force_cols != nl->list.force_cols + && rl->list.force_cols != nl->list.ncols) + || cl->list.vertical_cols != nl->list.vertical_cols + || cl->list.longest != nl->list.longest + || cl->list.nitems != nl->list.nitems + || cl->list.font != nl->list.font + /* Equiv. fontsets might have different values, but the same fonts, + so the next comparison is sloppy but not dangerous */ + || cl->list.fontset != nl->list.fontset + || cl->list.list != nl->list.list) { + CalculatedValues(cnew); + Layout(cnew, WidthFree(nl), HeightFree(nl), + &nl->core.width, &nl->core.height); + redraw = True; + } + + if (cl->list.list != nl->list.list || cl->list.nitems != nl->list.nitems) + nl->list.is_highlighted = nl->list.highlight = NO_HIGHLIGHT; + + if (cl->core.sensitive != nl->core.sensitive + || cl->core.ancestor_sensitive != nl->core.ancestor_sensitive) { + nl->list.highlight = NO_HIGHLIGHT; + redraw = True; + } + + return (redraw); +} + +static void +XawListDestroy(Widget w) +{ + ListWidget lw = (ListWidget)w; + XGCValues values; + + XGetGCValues(XtDisplay(w), lw->list.graygc, GCTile, &values); + XmuReleaseStippledPixmap(XtScreen(w), values.tile); + XtReleaseGC(w, lw->list.graygc); + XtReleaseGC(w, lw->list.revgc); + XtReleaseGC(w, lw->list.normgc); +} + +/* + * Function: + * XawListChange + * + * Parameters: + * w - list widget + * list - new list + * nitems - number of items in the list + * longest - length (in Pixels) of the longest element in the list + * resize - if True the the list widget will try to resize itself + * + * Description: + * Changes the list being used and shown. + * + * Note: + * If nitems of longest are <= 0 then they will be calculated + * If nitems is <= 0 then the list needs to be NULL terminated + */ +void +XawListChange(Widget w, char **list, int nitems, int longest, +#if NeedWidePrototypes + int resize_it +#else + Boolean resize_it +#endif +) +{ + ListWidget lw = (ListWidget)w; + Dimension new_width = XtWidth(w); + Dimension new_height = XtHeight(w); + + lw->list.list = list; + + if (nitems <= 0) + nitems = 0; + lw->list.nitems = nitems; + if (longest <= 0) + longest = 0; + + /* If the user passes 0 meaning "calculate it", it must be free */ + if (longest != 0) + lw->list.freedoms |= LongestLock; + else + lw->list.freedoms &= ~LongestLock; + + if (resize_it) + lw->list.freedoms &= ~WidthLock & ~HeightLock; + + lw->list.longest = longest; + + CalculatedValues(w); + + if (Layout(w, WidthFree(w), HeightFree(w), &new_width, &new_height)) + ChangeSize(w, new_width, new_height); + + lw->list.is_highlighted = lw->list.highlight = NO_HIGHLIGHT; + if (XtIsRealized(w)) + XawListRedisplay(w, NULL, NULL); +} + +void +XawListUnhighlight(Widget w) +{ + ListWidget lw = (ListWidget)w; + + lw->list.highlight = NO_HIGHLIGHT; + if (lw->list.is_highlighted != NO_HIGHLIGHT) + PaintItemName(w, lw->list.is_highlighted); +} + +void +XawListHighlight(Widget w, int item) +{ + ListWidget lw = (ListWidget)w; + + if (XtIsSensitive(w)) { + lw->list.highlight = item; + if (lw->list.is_highlighted != NO_HIGHLIGHT) + PaintItemName(w, lw->list.is_highlighted); + PaintItemName(w, item); + } +} + +/* + * Function: + * XawListShowCurrent + * + * Parameters: + * w - list widget + * + * Returns: + * Info about the currently highlighted object + */ +XawListReturnStruct * +XawListShowCurrent(Widget w) +{ + ListWidget lw = (ListWidget)w; + XawListReturnStruct *ret_val; + + ret_val = (XawListReturnStruct *)XtMalloc(sizeof(XawListReturnStruct)); + + ret_val->list_index = lw->list.highlight; + if (ret_val->list_index == XAW_LIST_NONE) + ret_val->string = ""; + else + ret_val->string = lw->list.list[ret_val->list_index]; + + return (ret_val); +} diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..951dc26 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,142 @@ +lib_LTLIBRARIES = + +# +# This doesn't appear to be used on any +# current systems -- it requires SUNSHLIB and !SHAREDCODE, +# but only sunLib.rules defines SUNSHLIB and that file also +# always defines SHAREDCODE. Go figure +# +# SHAREDLIB_SOURCES = sharedlib.c + +COMMON_SOURCES = \ + Actions.c \ + AllWidgets.c \ + AsciiSink.c \ + AsciiSrc.c \ + AsciiText.c \ + Box.c \ + Command.c \ + Converters.c \ + Dialog.c \ + DisplayList.c \ + Form.c \ + Grip.c \ + Label.c \ + List.c \ + MenuButton.c \ + MultiSrc.c \ + MultiSink.c \ + OS.c \ + Paned.c \ + Panner.c \ + Pixmap.c \ + Porthole.c \ + Private.h \ + Repeater.c \ + Scrollbar.c \ + Simple.c \ + SimpleMenu.c \ + Sme.c \ + SmeBSB.c \ + SmeLine.c \ + StripChart.c \ + Text.c \ + TextSink.c \ + TextSrc.c \ + TextAction.c \ + TextPop.c \ + TextTr.c \ + Toggle.c \ + Tree.c \ + Vendor.c \ + Viewport.c \ + XawIm.c \ + XawInit.c \ + XawI18n.c \ + XawI18n.h + +COMMON_CFLAGS = \ + $(CWARNFLAGS) + +COMMON_CPPFLAGS = \ + -I${top_srcdir}/include \ + -DPROJECT_ROOT=\"$(prefix)\" + +if BUILD_XAW6 + +lib_LTLIBRARIES += libXaw6.la + +libXaw6_la_CPPFLAGS = \ + $(COMMON_CPPFLAGS) + +libXaw6_la_CFLAGS = \ + $(COMMON_CFLAGS) \ + -DOLDXAW \ + $(XAW6_CFLAGS) + +libXaw6_la_SOURCES = \ + $(COMMON_SOURCES) + +libXaw6_la_LDFLAGS = -version-info 6:1:0 -no-undefined +libXaw6_la_LIBADD = $(XAW6_LIBS) + +if !PLATFORM_WIN32 +install-exec-hook:: +if PLATFORM_DARWIN + -rm -f $(DESTDIR)$(libdir)/libXaw.6.@LIBEXT@ + (cd $(DESTDIR)$(libdir) && ln -s libXaw6.6.@LIBEXT@ libXaw.6.@LIBEXT@) +else + -rm -f $(DESTDIR)$(libdir)/libXaw.@LIBEXT@.6 + (cd $(DESTDIR)$(libdir) && ln -s libXaw6.@LIBEXT@.6 libXaw.@LIBEXT@.6) +endif + +uninstall-local:: +if PLATFORM_DARWIN + -rm -f $(DESTDIR)$(libdir)/libXaw.6.@LIBEXT@ +else + -rm -f $(DESTDIR)$(libdir)/libXaw.@LIBEXT@.6 +endif +endif + +endif + +if BUILD_XAW7 + +lib_LTLIBRARIES += libXaw7.la + +libXaw7_la_CPPFLAGS = \ + $(COMMON_CPPFLAGS) + +libXaw7_la_CFLAGS = \ + $(COMMON_CFLAGS) \ + -DXAW7 \ + $(XAW7_CFLAGS) + +libXaw7_la_SOURCES = \ + $(COMMON_SOURCES) \ + Tip.c + +libXaw7_la_LDFLAGS = -version-info 7:0:0 -no-undefined +libXaw7_la_LIBADD = $(XAW7_LIBS) + +if !PLATFORM_WIN32 +install-exec-hook:: +if PLATFORM_DARWIN + -rm -f $(DESTDIR)$(libdir)/libXaw.7.@LIBEXT@ + (cd $(DESTDIR)$(libdir) && ln -s libXaw7.7.@LIBEXT@ libXaw.7.@LIBEXT@) +else + -rm -f $(DESTDIR)$(libdir)/libXaw.@LIBEXT@.7 + (cd $(DESTDIR)$(libdir) && ln -s libXaw7.@LIBEXT@.7 libXaw.@LIBEXT@.7) +endif + +uninstall-local:: +if PLATFORM_DARWIN + -rm -f $(DESTDIR)$(libdir)/libXaw.7.@LIBEXT@ +else + -rm -f $(DESTDIR)$(libdir)/libXaw.@LIBEXT@.7 +endif +endif + +endif + +EXTRA_DIST = sharedlib.c diff --git a/src/MenuButton.c b/src/MenuButton.c new file mode 100644 index 0000000..e190851 --- /dev/null +++ b/src/MenuButton.c @@ -0,0 +1,271 @@ +/* +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + */ + +/* + * MenuButton.c - Source code for MenuButton widget. + * + * This is the source code for the Athena MenuButton widget. + * It is intended to provide an easy method of activating pulldown menus. + * + * Date: May 2, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include "Private.h" + +/* + * Class Methods + */ +static void XawMenuButtonClassInitialize(void); +static void XawMenuButtonInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawMenuButtonDestroy(Widget); +static Boolean XawMenuButtonSetValues(Widget, Widget, Widget, ArgList, Cardinal*); + +/* + * Actions + */ +static void PopupMenu(Widget, XEvent*, String*, Cardinal*); + +/* + * Initialization + */ +#define superclass ((CommandWidgetClass)&commandClassRec) + +static char defaultTranslations[] = +":" "highlight()\n" +":" "reset()\n" +"Any:" "reset() PopupMenu()\n"; + +static char default_menu_name[] = "menu"; + +#define offset(field) XtOffsetOf(MenuButtonRec, field) +static XtResource resources[] = { + { + XtNmenuName, + XtCMenuName, + XtRString, + sizeof(String), + offset(menu_button.menu_name), + XtRString, + (XtPointer)default_menu_name + }, +}; +#undef offset + +static XtActionsRec actionsList[] = +{ + {"PopupMenu", PopupMenu}, +}; + +MenuButtonClassRec menuButtonClassRec = { + /* core */ + { + (WidgetClass)superclass, /* superclass */ + "MenuButton", /* class_name */ + sizeof(MenuButtonRec), /* size */ + XawMenuButtonClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawMenuButtonInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + actionsList, /* actions */ + XtNumber(actionsList), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawMenuButtonDestroy, /* destroy */ + XtInheritResize, /* resize */ + XtInheritExpose, /* expose */ + XawMenuButtonSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + defaultTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + XtInheritChangeSensitive /* change_sensitive */ + }, + /* label */ + { + NULL, /* extension */ + }, + /* command */ + { + NULL, /* extension */ + }, + /* menu_button */ + { + NULL, /* extension */ + }, +}; + +WidgetClass menuButtonWidgetClass = (WidgetClass)&menuButtonClassRec; + +/* + * Implementation + */ +static void +XawMenuButtonClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtRegisterGrabAction(PopupMenu, True, + ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync); +} + +/*ARGSUSED*/ +static void +XawMenuButtonInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + MenuButtonWidget mbw = (MenuButtonWidget)cnew; + + if (mbw->menu_button.menu_name != default_menu_name) + mbw->menu_button.menu_name = XtNewString(mbw->menu_button.menu_name); +} + +static void +XawMenuButtonDestroy(Widget w) +{ + MenuButtonWidget mbw = (MenuButtonWidget)w; + + if (mbw->menu_button.menu_name != default_menu_name) + XtFree(mbw->menu_button.menu_name); +} + +/*ARGSUSED*/ +static Boolean +XawMenuButtonSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + MenuButtonWidget mbw_old = (MenuButtonWidget)current; + MenuButtonWidget mbw_new = (MenuButtonWidget)cnew; + + if (mbw_old->menu_button.menu_name != mbw_new->menu_button.menu_name) { + if (mbw_old->menu_button.menu_name != default_menu_name) + XtFree(mbw_old->menu_button.menu_name); + if (mbw_new->menu_button.menu_name != default_menu_name) + mbw_new->menu_button.menu_name = + XtNewString(mbw_new->menu_button.menu_name); + } + + return (False); +} + +/*ARGSUSED*/ +static void +PopupMenu(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + MenuButtonWidget mbw = (MenuButtonWidget)w; + Widget menu = NULL, temp; + Arg arglist[2]; + Cardinal num_args; + int menu_x, menu_y, menu_width, menu_height, button_height; + Position button_x, button_y; + + temp = w; + while(temp != NULL) { + menu = XtNameToWidget(temp, mbw->menu_button.menu_name); + if (menu == NULL) + temp = XtParent(temp); + else + break; + } + + if (menu == NULL) { + char error_buf[BUFSIZ]; + + snprintf(error_buf, sizeof(error_buf), + "MenuButton: Could not find menu widget named %s.", + mbw->menu_button.menu_name); + XtAppWarning(XtWidgetToApplicationContext(w), error_buf); + return; + } + + if (!XtIsRealized(menu)) + XtRealizeWidget(menu); + + menu_width = XtWidth(menu) + (XtBorderWidth(menu) << 1); + button_height = XtHeight(w) + (XtBorderWidth(w) << 1); + menu_height = XtHeight(menu) + (XtBorderWidth(menu) << 1); + + XtTranslateCoords(w, 0, 0, &button_x, &button_y); + menu_x = button_x; + menu_y = button_y + button_height; + + if (menu_y >= 0) { + int scr_height = HeightOfScreen(XtScreen(menu)); + + if (menu_y + menu_height > scr_height) + menu_y = button_y - menu_height; + if (menu_y < 0) { + menu_y = scr_height - menu_height; + menu_x = button_x + XtWidth(w) + (XtBorderWidth(w) << 1); + if (menu_x + menu_width > WidthOfScreen(XtScreen(menu))) + menu_x = button_x - menu_width; + } + } + if (menu_y < 0) + menu_y = 0; + + if (menu_x >= 0) { + int scr_width = WidthOfScreen(XtScreen(menu)); + + if (menu_x + menu_width > scr_width) + menu_x = scr_width - menu_width; + } + if (menu_x < 0) + menu_x = 0; + + num_args = 0; + XtSetArg(arglist[num_args], XtNx, menu_x); num_args++; + XtSetArg(arglist[num_args], XtNy, menu_y); num_args++; + XtSetValues(menu, arglist, num_args); + + XtPopupSpringLoaded(menu); +} diff --git a/src/MultiSink.c b/src/MultiSink.c new file mode 100644 index 0000000..77eb42f --- /dev/null +++ b/src/MultiSink.c @@ -0,0 +1,975 @@ +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of OMRON not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. OMRON makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "XawI18n.h" +#include +#include +#include "Private.h" + +#ifdef GETLASTPOS +#undef GETLASTPOS /* We will use our own GETLASTPOS */ +#endif + +#define GETLASTPOS \ + XawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, True) + +/* + * Class Methods + */ +static void XawMultiSinkClassInitialize(void); +static void XawMultiSinkInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawMultiSinkDestroy(Widget); +static void XawMultiSinkResize(Widget); +static Boolean XawMultiSinkSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static int MaxLines(Widget, unsigned int); +static int MaxHeight(Widget, int); +static void SetTabs(Widget, int, short*); +static void DisplayText(Widget, int, int, + XawTextPosition, XawTextPosition, Bool); +static void InsertCursor(Widget, int, int, XawTextInsertState); +static void FindPosition(Widget, XawTextPosition, int, int, Bool, + XawTextPosition*, int*, int*); +static void FindDistance(Widget, XawTextPosition, int, XawTextPosition, int*, + XawTextPosition*, int*); +static void Resolve(Widget, XawTextPosition, int, int, XawTextPosition*); +static void GetCursorBounds(Widget, XRectangle*); + +/* + * Prototypes + */ +static void GetGC(MultiSinkObject); +static int CharWidth(MultiSinkObject, XFontSet, int, wchar_t); +static unsigned int PaintText(Widget w, GC gc, int x, int y, + wchar_t *buf, int len, Bool); + +/* + * Defined in TextSink.c + */ +void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned); + +/* + * Initialization + */ +static wchar_t wspace[2]; + +#define offset(field) XtOffsetOf(MultiSinkRec, multi_sink.field) +static XtResource resources[] = { + { + XtNfontSet, + XtCFontSet, + XtRFontSet, + sizeof(XFontSet), + offset(fontset), + XtRString, + XtDefaultFontSet + }, + { + XtNecho, + XtCOutput, + XtRBoolean, + sizeof(Boolean), + offset(echo), + XtRImmediate, + (XtPointer)True + }, + { + XtNdisplayNonprinting, + XtCOutput, + XtRBoolean, + sizeof(Boolean), + offset(display_nonprinting), + XtRImmediate, + (XtPointer)True + }, +}; +#undef offset + +#define SuperClass (&textSinkClassRec) +MultiSinkClassRec multiSinkClassRec = { + /* object */ + { + (WidgetClass)SuperClass, /* superclass */ + "MultiSink", /* class_name */ + sizeof(MultiSinkRec), /* widget_size */ + XawMultiSinkClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawMultiSinkInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* obj1 */ + NULL, /* obj2 */ + 0, /* obj3 */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* obj4 */ + False, /* obj5 */ + False, /* obj6 */ + False, /* obj7 */ + XawMultiSinkDestroy, /* destroy */ + (XtProc)XawMultiSinkResize, /* obj8 */ + NULL, /* obj9 */ + XawMultiSinkSetValues, /* set_values */ + NULL, /* set_values_hook */ + NULL, /* obj10 */ + NULL, /* get_values_hook */ + NULL, /* obj11 */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* obj12 */ + NULL, /* obj13 */ + NULL, /* obj14 */ + NULL, /* extension */ + }, + /* text_sink */ + { + DisplayText, /* DisplayText */ + InsertCursor, /* InsertCursor */ + XtInheritClearToBackground, /* ClearToBackground */ + FindPosition, /* FindPosition */ + FindDistance, /* FindDistance */ + Resolve, /* Resolve */ + MaxLines, /* MaxLines */ + MaxHeight, /* MaxHeight */ + SetTabs, /* SetTabs */ + GetCursorBounds, /* GetCursorBounds */ + }, + /* multi_sink */ + { + NULL, /* extension */ + } +}; + +WidgetClass multiSinkObjectClass = (WidgetClass)&multiSinkClassRec; + +/* + * Implementation + */ +static int +CharWidth(MultiSinkObject sink, XFontSet fontset, int x, wchar_t c) +{ + int width = 0; + + if (c == _Xaw_atowc(XawLF)) + return (0); + + if (c == _Xaw_atowc(XawTAB)) { + int i; + Position *tab; + + width = x; + /* Adjust for Left Margin. */ + x -= ((TextWidget)XtParent((Widget)sink))->text.left_margin; + + i = 0; + tab = sink->text_sink.tabs; + /*CONSTCOND*/ + while (1) { + if (x < *tab) + return (*tab - x); + /* Start again */ + if (++i >= sink->text_sink.tab_count) { + x -= *tab; + i = 0; + tab = sink->text_sink.tabs; + if (width == x) + return (0); + } + else + ++tab; + } + /*NOTREACHED*/ + } + + if (XwcTextEscapement(fontset, &c, 1) == 0) { + if (sink->multi_sink.display_nonprinting) + c = _Xaw_atowc('@'); + else + c = _Xaw_atowc(XawSP); + } + + /* + * if more efficiency(suppose one column is one ASCII char) + + width = XwcGetColumn(fontset->font_charset, fontset->num_of_fonts, c) * + fontset->font_struct_list[0]->min_bounds.width; + * + * WARNING: Very Slower!!! + * + * Li Yuhong. + */ + + width = XwcTextEscapement(fontset, &c, 1); + + return (width); +} + +/* + * Function: + * PaintText + * + * Parameters: + * w - text sink object + * gc - gc to paint text + * x - location to paint the text + * y - "" + * buf - buffer and length of text to paint + * len - "" + * clear_bg - clear background before drawing ? + * + * Description: + * Actually paints the text into the window. + * + * Returns: + * The width of the text painted + */ +static unsigned int +PaintText(Widget w, GC gc, int x, int y, wchar_t *buf, int len, Bool clear_bg) +{ + MultiSinkObject sink = (MultiSinkObject)w; + TextWidget ctx = (TextWidget)XtParent(w); + XFontSet fontset = sink->multi_sink.fontset; + unsigned int width = XwcTextEscapement(fontset, buf, len); + + if (((int)width) <= -x) /* Don't draw if we can't see it */ + return (width); + + if (clear_bg) { + XFontSetExtents *ext = XExtentsOfFontSet(fontset); + + _XawTextSinkClearToBackground(w, x, y - abs(ext->max_logical_extent.y), + width, ext->max_logical_extent.height); + XwcDrawString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, x, y, buf, len); + } + else + XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, + x, y, buf, len); + + return (width); +} + +/* Sink Object Functions */ +/* + * This function does not know about drawing more than one line of text + */ +static void +DisplayText(Widget w, int x, int y, + XawTextPosition pos1, XawTextPosition pos2, Bool highlight) +{ + TextWidget ctx = (TextWidget)XtParent(w); + MultiSinkObject sink = (MultiSinkObject)w; + XFontSet fontset = sink->multi_sink.fontset; + Widget source = XawTextGetSource(XtParent(w)); + wchar_t buf[256]; + XFontSetExtents *ext = XExtentsOfFontSet(fontset); + int j, k; + XawTextBlock blk; + GC gc, invgc, tabgc; + int max_x; + Bool clear_bg; + + if (!sink->multi_sink.echo || !ctx->text.lt.lines) + return; + + max_x = (int)XtWidth(ctx) - ctx->text.r_margin.right; + clear_bg = !highlight && ctx->core.background_pixmap != XtUnspecifiedPixmap; + + gc = highlight ? sink->multi_sink.invgc : sink->multi_sink.normgc; + invgc = highlight ? sink->multi_sink.normgc : sink->multi_sink.invgc; + + if (highlight && sink->multi_sink.xorgc) + tabgc = sink->multi_sink.xorgc; + else + tabgc = invgc; + + y += abs(ext->max_logical_extent.y); + for (j = 0; pos1 < pos2;) { + pos1 = XawTextSourceRead(source, pos1, &blk, (int) pos2 - pos1); + for (k = 0; k < blk.length; k++) { + if ((unsigned) j >= (sizeof(buf) / sizeof(wchar_t)) - 1) { + /* buffer full, dump the text */ + if ((x += PaintText(w, gc, x, y, buf, j, clear_bg)) >= max_x) + return; + j = 0; + } + buf[j] = ((wchar_t *)blk.ptr)[k]; + if (buf[j] == _Xaw_atowc(XawLF)) + continue; + + else if (buf[j] == _Xaw_atowc(XawTAB)) { + unsigned int width; + + if (j != 0 && + (x += PaintText(w, gc, x, y, buf, j, clear_bg)) >= max_x) + return; + + width = CharWidth(sink, fontset, x, _Xaw_atowc(XawTAB)); + if (clear_bg) + _XawTextSinkClearToBackground(w, + x, y - abs(ext->max_logical_extent.y), + width, ext->max_logical_extent.height); + else + XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), + tabgc, x, + y - abs(ext->max_logical_extent.y), + width, + ext->max_logical_extent.height); + x += width; + j = -1; + } + else if (XwcTextEscapement(sink->multi_sink.fontset, &buf[j], 1) + == 0) { + if (sink->multi_sink.display_nonprinting) + buf[j] = _Xaw_atowc('@'); + else + buf[j] = _Xaw_atowc(XawSP); + } + j++; + } + } + + if (j > 0) + (void)PaintText(w, gc, x, y, buf, j, clear_bg); +} + +/* + * Function: + * GetCursorBounds + * + * Parameters: + * w - text sink object + * rect - X rectangle to return the cursor bounds + * + * Description: + * Returns the size and location of the cursor. + */ +static void +GetCursorBounds(Widget w, XRectangle *rect) +{ + MultiSinkObject sink = (MultiSinkObject)w; + + rect->width = CharWidth(sink, sink->multi_sink.fontset, 0, _Xaw_atowc(XawSP)); + rect->height = (XExtentsOfFontSet(sink->multi_sink.fontset) + ->max_logical_extent.height); + rect->x = sink->multi_sink.cursor_x; + rect->y = sink->multi_sink.cursor_y - (short)rect->height; +} + +/* + * The following procedure manages the "insert" cursor + */ +static void +InsertCursor(Widget w, int x, int y, XawTextInsertState state) +{ + MultiSinkObject sink = (MultiSinkObject)w; + XFontSet fontset = sink->multi_sink.fontset; + Widget ctx = XtParent(w); + XawTextPosition position = XawTextGetInsertionPoint(ctx); + + if (XtIsRealized(ctx)) { + int fheight, fdiff; + XawTextBlock block; + wchar_t c; + XawTextPosition selection_start, selection_end; + Boolean has_selection; + XFontSetExtents *ext = XExtentsOfFontSet(fontset); + + XawTextGetSelectionPos((Widget)ctx, &selection_start, &selection_end); + has_selection = selection_start != selection_end; + + fheight = ext->max_logical_extent.height; + fdiff = fheight - abs(ext->max_logical_extent.y); + + if ((sink->multi_sink.cursor_position != position || state == XawisOff) + && !has_selection && sink->multi_sink.laststate != XawisOff) { + wchar_t *ochar; + + (void)XawTextSourceRead(XawTextGetSource(ctx), + sink->multi_sink.cursor_position, + &block, 1); + if (!block.length) + ochar = NULL; + else { + c = ((wchar_t *)block.ptr)[0]; + if (c == _Xaw_atowc(XawLF)) + ochar = NULL; + else if (c == _Xaw_atowc(XawTAB)) + ochar = wspace; + else + ochar = (wchar_t *)block.ptr; + } + + if (!ochar) + _XawTextSinkClearToBackground(w, sink->multi_sink.cursor_x, + (sink->multi_sink.cursor_y - 1 - + fheight), CharWidth(sink, fontset, + 0, wspace[0]), + fheight); + else { + if (XwcTextEscapement(sink->multi_sink.fontset, ochar, 1) != 0) + DisplayText(w, sink->multi_sink.cursor_x, + sink->multi_sink.cursor_y - 1 - fheight, + sink->multi_sink.cursor_position, + sink->multi_sink.cursor_position + 1, + False); + else + PaintText(w, sink->multi_sink.normgc, + sink->multi_sink.cursor_x, + sink->multi_sink.cursor_y - 1 - fdiff, + ochar, 1, + ctx->core.background_pixmap != XtUnspecifiedPixmap); + } + } + + if (!has_selection && state != XawisOff) { + wchar_t *nchar; + Boolean focus = ((TextWidget)ctx)->text.hasfocus; + + (void)XawTextSourceRead(XawTextGetSource(ctx), + position, &block, 1); + c = ((wchar_t *)block.ptr)[0]; + if (!block.length || c == _Xaw_atowc(XawLF) + || c == _Xaw_atowc(XawTAB)) + nchar = wspace; + else + nchar = (wchar_t *)block.ptr; + + if (focus) { + if (XwcTextEscapement(sink->multi_sink.fontset, nchar, 1) != 0) + XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), + fontset, sink->multi_sink.invgc, + x, (y - 1 - fdiff), nchar, 1); + else + DisplayText(w, x, y - 1 - fheight, + position, position + 1, True); + } + else + XDrawRectangle(XtDisplay(ctx), XtWindow(ctx), + sink->multi_sink.xorgc ? + sink->multi_sink.xorgc : sink->multi_sink.normgc, + x, y - 1 - fheight, + CharWidth(sink, fontset, 0, *nchar) - 1, + fheight - 1); + } + } + + sink->multi_sink.cursor_x = x; + sink->multi_sink.cursor_y = y; + sink->multi_sink.laststate = state; + sink->multi_sink.cursor_position = position; +} + +/* + * Given two positions, find the distance between them + */ +static void +FindDistance(Widget w, XawTextPosition fromPos, int fromx, + XawTextPosition toPos, int *resWidth, + XawTextPosition *resPos, int *resHeight) +{ + MultiSinkObject sink = (MultiSinkObject)w; + XFontSet fontset = sink->multi_sink.fontset; + TextWidget ctx = (TextWidget)XtParent(w); + Widget source = ctx->text.source; + XawTextPosition idx, pos; + wchar_t c; + XFontSetExtents *ext = XExtentsOfFontSet(fontset); + XawTextBlock blk; + int i, rWidth; + + pos = XawTextSourceRead(source, fromPos, &blk, toPos - fromPos); + rWidth = 0; + for (i = 0, idx = fromPos; idx < toPos; i++, idx++) { + if (i >= blk.length) { + i = 0; + XawTextSourceRead(source, pos, &blk, toPos - pos); + if (blk.length == 0) + break; + } + c = ((wchar_t *)blk.ptr)[i]; + rWidth += CharWidth(sink, fontset, fromx + rWidth, c); + if (c == _Xaw_atowc(XawLF)) { + idx++; + break; + } + } + + *resPos = idx; + *resWidth = rWidth; + *resHeight = ext->max_logical_extent.height; +} + +static void +FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width, + Bool stopAtWordBreak, XawTextPosition *resPos, int *resWidth, + int *resHeight) +{ + MultiSinkObject sink = (MultiSinkObject)w; + TextWidget ctx = (TextWidget)XtParent(w); + Widget source = ctx->text.source; + XFontSet fontset = sink->multi_sink.fontset; + XawTextPosition idx, pos, whiteSpacePosition = 0; + int i, lastWidth, whiteSpaceWidth, rWidth; + Boolean whiteSpaceSeen; + wchar_t c; + XFontSetExtents *ext = XExtentsOfFontSet(fontset); + XawTextBlock blk; + + pos = XawTextSourceRead(source, fromPos, &blk, BUFSIZ); + rWidth = lastWidth = whiteSpaceWidth = 0; + whiteSpaceSeen = False; + c = 0; + + for (i = 0, idx = fromPos; rWidth <= width; i++, idx++) { + if (i >= blk.length) { + i = 0; + pos = XawTextSourceRead(source, pos, &blk, BUFSIZ); + if (blk.length == 0) + break; + } + c = ((wchar_t *)blk.ptr)[i]; + lastWidth = rWidth; + rWidth += CharWidth(sink, fontset, fromx + rWidth, c); + + if (c == _Xaw_atowc(XawLF)) { + idx++; + break; + } + else if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB)) + && rWidth <= width) { + whiteSpaceSeen = True; + whiteSpacePosition = idx; + whiteSpaceWidth = rWidth; + } + } + + if (rWidth > width && idx > fromPos) { + idx--; + rWidth = lastWidth; + if (stopAtWordBreak && whiteSpaceSeen) { + idx = whiteSpacePosition + 1; + rWidth = whiteSpaceWidth; + } + } + + if (idx >= ctx->text.lastPos && c != _Xaw_atowc(XawLF)) + idx = ctx->text.lastPos + 1; + + *resPos = idx; + *resWidth = rWidth; + *resHeight = ext->max_logical_extent.height; +} + +static void +Resolve(Widget w, XawTextPosition pos, int fromx, int width, + XawTextPosition *pos_return) +{ + int resWidth, resHeight; + Widget source = XawTextGetSource(XtParent(w)); + + FindPosition(w, pos, fromx, width, False, pos_return, &resWidth, &resHeight); + if (*pos_return > GETLASTPOS) + *pos_return = GETLASTPOS; +} + +static void +GetGC(MultiSinkObject sink) +{ + XtGCMask valuemask = (GCGraphicsExposures | GCClipXOrigin | + GCForeground | GCBackground); + XGCValues values; + + /* XXX We dont want do share a gc that will change the clip-mask */ + values.clip_x_origin = (long)sink; + values.clip_mask = None; + values.graphics_exposures = False; + + values.foreground = sink->text_sink.foreground; + values.background = sink->text_sink.background; + + sink->multi_sink.normgc = XtAllocateGC((Widget)sink, 0, valuemask, &values, + GCFont | GCClipMask, 0); + + values.foreground = sink->text_sink.background; +#ifndef OLDXAW + values.background = sink->text_sink.cursor_color; +#else + values.background = sink->text_sink.foreground; +#endif + sink->multi_sink.invgc = XtAllocateGC((Widget)sink, 0, valuemask, &values, + GCFont | GCClipMask, 0); +#ifndef OLDXAW + if (sink->text_sink.cursor_color != sink->text_sink.foreground) { + values.foreground = sink->text_sink.cursor_color; + values.background = sink->text_sink.foreground; + sink->multi_sink.xorgc = XtAllocateGC((Widget)sink, 0, valuemask, + &values, GCFont | GCClipMask, 0); + } + else +#endif /* OLDXAW */ + sink->multi_sink.xorgc = NULL; + + XawMultiSinkResize((Widget)sink); +} + +static void +XawMultiSinkClassInitialize(void) +{ + wspace[0] = _Xaw_atowc(XawSP); + XawInitializeWidgetSet(); +} + +/* + * Function: + * XawMultiSinkInitialize + * + * Parameters: + * request - requested and new values for the object instance + * cnew - "" + * + * Description: + * Initializes the TextSink Object. + */ +/* ARGSUSED */ +static void +XawMultiSinkInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + MultiSinkObject sink = (MultiSinkObject)cnew; + + GetGC(sink); + + if (!sink->multi_sink.fontset) XtError("Aborting: no fontset found\n"); + + sink->multi_sink.cursor_position = 0; + sink->multi_sink.laststate = XawisOff; + sink->multi_sink.cursor_x = sink->multi_sink.cursor_y = 0; +} + +/* + * Function: + * XawMultiSinkDestroy + * + * Parameters: + * w - MultiSink Object + * + * Description: + * This function cleans up when the object is destroyed. + */ +static void +XawMultiSinkDestroy(Widget w) +{ + MultiSinkObject sink = (MultiSinkObject)w; + + XtReleaseGC(w, sink->multi_sink.normgc); + XtReleaseGC(w, sink->multi_sink.invgc); + if (sink->multi_sink.xorgc) + XtReleaseGC(w, sink->multi_sink.xorgc); + sink->multi_sink.normgc = + sink->multi_sink.invgc = + sink->multi_sink.xorgc = NULL; +} + +static void +XawMultiSinkResize(Widget w) +{ + TextWidget ctx = (TextWidget)XtParent(w); + MultiSinkObject sink = (MultiSinkObject)w; + XRectangle rect; + int width, height; + + if (w->core.widget_class != multiSinkObjectClass) + return; + + rect.x = ctx->text.r_margin.left; + rect.y = ctx->text.r_margin.top; + width = (int)XtWidth(ctx) - + (int)ctx->text.r_margin.right - (int)ctx->text.r_margin.left; + height = (int)XtHeight(ctx) - + (int)ctx->text.r_margin.top - (int)ctx->text.r_margin.bottom; + rect.width = width; + rect.height = height; + + if (sink->multi_sink.normgc) { + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), sink->multi_sink.normgc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), sink->multi_sink.normgc, None); + } + if (sink->multi_sink.invgc) { + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), sink->multi_sink.invgc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), sink->multi_sink.invgc, None); + } + if (sink->multi_sink.xorgc) { + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), sink->multi_sink.xorgc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), sink->multi_sink.xorgc, None); + } +} + +/* + * Function: + * XawMultiSinkSetValues + * + * Parameters: + * current - current state of the object + * request - what was requested + * cnew - what the object will become + * + * Description: + * Sets the values for the MultiSink. + * + * Returns: + * True if redisplay is needed + */ +/*ARGSUSED*/ +static Boolean +XawMultiSinkSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + MultiSinkObject w = (MultiSinkObject)cnew; + MultiSinkObject old_w = (MultiSinkObject)current; + + /* Font set is not in the GC! Do not make a new GC when font set changes! */ + + if (w->multi_sink.fontset != old_w->multi_sink.fontset) { + ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; +#ifndef NO_TAB_FIX + SetTabs((Widget)w, w->text_sink.tab_count, w->text_sink.char_tabs); +#endif + } + + if (w->text_sink.background != old_w->text_sink.background + || w->text_sink.foreground != old_w->text_sink.foreground +#ifndef OLDXAW + || w->text_sink.cursor_color != old_w->text_sink.cursor_color +#endif + ) { + XtReleaseGC(cnew, w->multi_sink.normgc); + XtReleaseGC(cnew, w->multi_sink.invgc); + if (w->multi_sink.xorgc) + XtReleaseGC(cnew, w->multi_sink.xorgc); + GetGC(w); + ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; + } + else if (w->multi_sink.echo != old_w->multi_sink.echo + || w->multi_sink.display_nonprinting + != old_w->multi_sink.display_nonprinting) + ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; + + return (False); +} + +/* + * Function: + * MaxLines + * + * Parameters: + * w - MultiSink Object + * height - height to fit lines into + * + * Description: + * Finds the Maximum number of lines that will fit in a given height. + * + * Returns: + * The number of lines that will fit + */ +/*ARGSUSED*/ +static int +MaxLines(Widget w, unsigned int height) +{ + MultiSinkObject sink = (MultiSinkObject)w; + int font_height; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + + font_height = ext->max_logical_extent.height; + return (height / font_height); +} + +/* + * Function: + * MaxHeight + * + * Parameters: + * w - MultiSink Object + * lines - number of lines + * + * Description: + * Finds the Minium height that will contain a given number lines. + * Returns: + * The height + */ +/*ARGSUSED*/ +static int +MaxHeight(Widget w, int lines) +{ + MultiSinkObject sink = (MultiSinkObject)w; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + + return (lines * ext->max_logical_extent.height); +} + +/* + * Function: + * SetTabs + * + * Arguments: + * w - MultiSink Object + * tab_count - number of tabs in the list + * tabs - text positions of the tabs + * + * Description: + * Sets the Tab stops. + */ +static void +SetTabs(Widget w, int tab_count, short* tabs) +{ + MultiSinkObject sink = (MultiSinkObject)w; + int i; + Atom XA_FIGURE_WIDTH; + unsigned long figure_width = 0; + XFontStruct *font; + + /* + * Bug: + * Suppose the first font of fontset stores the unit of column. + * + * By Li Yuhong, Mar. 14, 1991 + */ + { + XFontStruct **f_list; + char **f_name; + + (void)XFontsOfFontSet(sink->multi_sink.fontset, &f_list, &f_name); + font = f_list[0]; + } + + /* + * Find the figure width of the current font + */ + XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", False); + if (XA_FIGURE_WIDTH != None + && (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width) + || figure_width == 0)) { + if (font->per_char && font->min_char_or_byte2 <= '$' + && font->max_char_or_byte2 >= '$') + figure_width = font->per_char['$' - font->min_char_or_byte2].width; + else + figure_width = font->max_bounds.width; + } + + if (tab_count > sink->text_sink.tab_count) { + sink->text_sink.tabs = (Position *) + XtRealloc((char *)sink->text_sink.tabs, + (Cardinal)(tab_count * sizeof(Position))); + sink->text_sink.char_tabs = (short *) + XtRealloc((char *)sink->text_sink.char_tabs, + (Cardinal)(tab_count * sizeof(short))); + } + + for (i = 0 ; i < tab_count ; i++) { + sink->text_sink.tabs[i] = tabs[i] * figure_width; + sink->text_sink.char_tabs[i] = tabs[i]; + } + + sink->text_sink.tab_count = tab_count; + +#ifndef NO_TAB_FIX + ((TextWidget)XtParent(w))->text.redisplay_needed = True; +#endif +} + +void +_XawMultiSinkPosToXY(Widget w, XawTextPosition pos, Position *x, Position *y) +{ + MultiSinkObject sink = (MultiSinkObject)((TextWidget)w)->text.sink; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + + _XawTextPosToXY(w, pos, x, y); + *y += abs(ext->max_logical_extent.y); +} diff --git a/src/MultiSrc.c b/src/MultiSrc.c new file mode 100644 index 0000000..148a178 --- /dev/null +++ b/src/MultiSrc.c @@ -0,0 +1,1617 @@ +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name OMRON not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Chris Peterson MIT X Consortium + * Li Yuhong OMRON Corporation + * Frank Sheeran OMRON Corporation + * + * Much code taken from X11R3 String and Disk Sources. + */ + +/* + +Copyright 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "XawI18n.h" +#include "Private.h" + +#include +#include +#include + +#define MAGIC_VALUE ((XawTextPosition)-1) +#define streq(a, b) (strcmp((a), (b)) == 0) + +#ifdef X_NOT_POSIX +#define Off_t long +#define Size_t unsigned int +#else +#define Off_t off_t +#define Size_t size_t +#endif + + +/* + * Class Methods + */ +static XawTextPosition ReadText(Widget, XawTextPosition, XawTextBlock*, int); +static int ReplaceText(Widget, XawTextPosition, XawTextPosition, + XawTextBlock*); +static XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType, + XawTextScanDirection, int, Bool); +static XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection, + XawTextBlock*); +static void XawMultiSrcClassInitialize(void); +static void XawMultiSrcDestroy(Widget); +static void XawMultiSrcInitialize(Widget, Widget, ArgList, Cardinal*); +static Boolean XawMultiSrcSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static void XawMultiSrcGetValuesHook(Widget, ArgList, Cardinal*); + +/* + * Prototypes + */ +static MultiPiece *AllocNewPiece(MultiSrcObject, MultiPiece*); +static void BreakPiece(MultiSrcObject, MultiPiece*); +static Boolean CvtMultiTypeToString(Display*, XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr, XtPointer*); +static void CvtStringToMultiType(XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr); +static MultiPiece *FindPiece(MultiSrcObject, XawTextPosition, + XawTextPosition*); +static void FreeAllPieces(MultiSrcObject); +static FILE *InitStringOrFile(MultiSrcObject, Bool); +static void LoadPieces(MultiSrcObject, FILE*, char*); +static void RemovePiece(MultiSrcObject, MultiPiece*); +static void RemoveOldStringOrFile(MultiSrcObject, Bool); +static String StorePiecesInString(MultiSrcObject); +static Bool WriteToFile(String, String); +static void GetDefaultPieceSize(Widget, int, XrmValue*); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(MultiSrcRec, multi_src.field) +static XtResource resources[] = { + { + XtNstring, + XtCString, + XtRString, + sizeof(XtPointer), + offset(string), + XtRPointer, + NULL + }, + { + XtNtype, + XtCType, + XtRMultiType, + sizeof(XawAsciiType), + offset(type), + XtRImmediate, + (XtPointer)XawAsciiString + }, + { + XtNdataCompression, + XtCDataCompression, + XtRBoolean, + sizeof(Boolean), + offset(data_compression), + XtRImmediate, + (XtPointer)False + }, + { + XtNpieceSize, + XtCPieceSize, + XtRInt, + sizeof(XawTextPosition), + offset(piece_size), + XtRCallProc, + (XtPointer)GetDefaultPieceSize + }, +#ifdef OLDXAW + { + XtNcallback, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + offset(callback), + XtRCallback, + (XtPointer)NULL + }, +#endif + { + XtNuseStringInPlace, + XtCUseStringInPlace, + XtRBoolean, + sizeof(Boolean), + offset(use_string_in_place), + XtRImmediate, + (XtPointer)False + }, + { + XtNlength, + XtCLength, + XtRInt, + sizeof(int), + offset(multi_length), + XtRImmediate, + (XtPointer)MAGIC_VALUE + }, +}; +#undef offset + +#define superclass (&textSrcClassRec) +MultiSrcClassRec multiSrcClassRec = { + /* object */ + { + (WidgetClass)superclass, /* superclass */ + "MultiSrc", /* class_name */ + sizeof(MultiSrcRec), /* widget_size */ + XawMultiSrcClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawMultiSrcInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* obj1 */ + NULL, /* obj2 */ + 0, /* obj3 */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* obj4 */ + False, /* obj5 */ + False, /* obj6 */ + False, /* obj7 */ + XawMultiSrcDestroy, /* destroy */ + NULL, /* obj8 */ + NULL, /* obj9 */ + XawMultiSrcSetValues, /* set_values */ + NULL, /* set_values_hook */ + NULL, /* obj10 */ + XawMultiSrcGetValuesHook, /* get_values_hook */ + NULL, /* obj11 */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* obj12 */ + NULL, /* obj13 */ + NULL, /* obj14 */ + NULL, /* extension */ + }, + /* text_src */ + { + ReadText, /* Read */ + ReplaceText, /* Replace */ + Scan, /* Scan */ + Search, /* Search */ + XtInheritSetSelection, /* SetSelection */ + XtInheritConvertSelection, /* ConvertSelection */ + }, + /* multi_src */ + { + NULL, /* extension */ + }, +}; + +WidgetClass multiSrcObjectClass = (WidgetClass)&multiSrcClassRec; + +static XrmQuark Qstring, Qfile; + +/* + * Implementation + */ +static void +XawMultiSrcClassInitialize(void) +{ + XawInitializeWidgetSet(); + Qstring = XrmPermStringToQuark(XtEstring); + Qfile = XrmPermStringToQuark(XtEfile); + XtAddConverter(XtRString, XtRMultiType, CvtStringToMultiType, NULL, 0); + XtSetTypeConverter(XtRMultiType, XtRString, CvtMultiTypeToString, NULL, 0, + XtCacheNone, NULL); +} + +/* + * Function: + * XawMultiSrcInitialize + * + * Parameters: + * request - widget requested by the argument list + * cnew - the new widget with both resource and non resource values + * args - (unused) + * num_args - (unused) + * + * Description: + * Initializes the multi src object + */ +/*ARGSUSED*/ +static void +XawMultiSrcInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + MultiSrcObject src = (MultiSrcObject)cnew; + FILE *file; + + /* + * Set correct flags (override resources) depending upon widget class + */ +#ifdef OLDXAW + src->multi_src.changes = False; +#else + src->text_src.changed = False; +#endif + src->multi_src.allocated_string = False; + + if (src->multi_src.use_string_in_place && src->multi_src.string == NULL) + src->multi_src.use_string_in_place = False; + + file = InitStringOrFile(src, src->multi_src.type == XawAsciiFile); + LoadPieces(src, file, NULL); + + if (file != NULL) + fclose(file); + src->text_src.text_format = XawFmtWide; +} + +/* + * Function: + * ReadText + * + * Parameters: + * w - MultiSource object + * pos - position of the text to retrieve + * text - text block that will contain returned text + * length - maximum number of characters to read + * + * Description: + * This function reads the source. + * + * Returns: + * The character position following the retrieved text. + */ +static XawTextPosition +ReadText(Widget w, XawTextPosition pos, XawTextBlock *text, int length) +{ + MultiSrcObject src = (MultiSrcObject)w; + XawTextPosition count, start; + MultiPiece *piece = FindPiece(src, pos, &start); + + text->format = XawFmtWide; + text->firstPos = pos; + text->ptr = (char *)(piece->text + (pos - start)); + count = piece->used - (pos - start); + text->length = Max(0, (length > count) ? count : length); + + return (pos + text->length); +} + +/* + * Function: + * ReplaceText + * + * Parameters: + * w - MultiSource object + * startPos - ends of text that will be removed + * endPos - "" + * text - new text to be inserted into buffer at startPos + * + * Description: + * Replaces a block of text with new text. + * + * Returns: + * XawEditDone on success, XawEditError otherwise + */ +/*ARGSUSED*/ +static int +ReplaceText(Widget w, XawTextPosition startPos, XawTextPosition endPos, + XawTextBlock *u_text_p) +{ + MultiSrcObject src = (MultiSrcObject)w; + MultiPiece *start_piece, *end_piece, *temp_piece; + XawTextPosition start_first, end_first; + int length, firstPos; + wchar_t *wptr; + Bool local_artificial_block = False; + XawTextBlock text; + + /* STEP 1: The user handed me a text block called `u_text' that may be + * in either FMTWIDE or FMT8BIT (ie MB.) Later code needs the block + * `text' to hold FMTWIDE. So, this copies `u_text' to `text', and if + * `u_text' was MB, I knock it up to WIDE + */ + if (u_text_p->length == 0) /* if so, the block contents never ref'd */ + text.length = 0; + + else if (u_text_p->format == XawFmtWide) { + local_artificial_block = False; /* don't have to free it ourselves */ + text.firstPos = u_text_p->firstPos; + text.length = u_text_p->length; + text.ptr = u_text_p->ptr; + } + else { + /* + * WARNING! u_text->firstPos and length are in units of CHAR, + * not CHARACTERS! + */ + local_artificial_block = True; /* have to free it ourselves */ + text.firstPos = 0; + text.length = u_text_p->length; /* _XawTextMBToWC converts this + * to wchar len + */ + + text.ptr = (char*)_XawTextMBToWC(XtDisplay(XtParent(w)), + &u_text_p->ptr[u_text_p->firstPos], + &text.length); + + /* I assert the following assignment is not needed - since Step 4 + depends on length, it has no need of a terminating NULL. I think + the ASCII-version has the same needless NULL. */ + /*((wchar_t*)text.ptr)[ text.length ] = NULL;*/ + } + + /* STEP 2: some initialization... */ + if (src->text_src.edit_mode == XawtextRead) + return (XawEditError); + + start_piece = FindPiece(src, startPos, &start_first); + end_piece = FindPiece(src, endPos, &end_first); + + /* STEP 3: remove the empty pieces... */ + if (start_piece != end_piece) { + temp_piece = start_piece->next; + + /* If empty and not the only piece then remove it */ + if (((start_piece->used = startPos - start_first) == 0) + && !(start_piece->next == NULL && start_piece->prev == NULL)) + RemovePiece(src, start_piece); + + while (temp_piece != end_piece) { + temp_piece = temp_piece->next; + RemovePiece(src, temp_piece->prev); + } + end_piece->used -= endPos - end_first; + if (end_piece->used != 0) + memmove(end_piece->text, end_piece->text + endPos - end_first, + end_piece->used * sizeof(wchar_t)); + } + else { /* We are fully in one piece */ + if ((start_piece->used -= endPos - startPos) == 0) { + if (!(start_piece->next == NULL && start_piece->prev == NULL)) + RemovePiece(src, start_piece); + } + else { + memmove(start_piece->text + (startPos - start_first), + start_piece->text + (endPos - start_first), + (start_piece->used - (startPos - start_first)) * + sizeof(wchar_t)); + if (src->multi_src.use_string_in_place && + ((src->multi_src.length - (endPos - startPos)) + < src->multi_src.piece_size - 1)) + start_piece->text[src->multi_src.length - (endPos - startPos)] = + (wchar_t)0; + } + } + + src->multi_src.length += text.length -(endPos - startPos); + + /* STEP 4: insert the new stuff */ + if ( text.length != 0) { + start_piece = FindPiece(src, startPos, &start_first); + length = text.length; + firstPos = text.firstPos; + + while (length > 0) { + wchar_t *ptr; + int fill; + + if (src->multi_src.use_string_in_place) { + if (start_piece->used == src->multi_src.piece_size - 1) { + + /* + * The string is used in place, then the string + * is not allowed to grow + */ + start_piece->used = src->multi_src.length = + src->multi_src.piece_size - 1; + + start_piece->text[src->multi_src.length] = (wchar_t)0; + return (XawEditError); + } + } + + if (start_piece->used == src->multi_src.piece_size) { + BreakPiece(src, start_piece); + start_piece = FindPiece(src, startPos, &start_first); + } + + fill = Min((int)(src->multi_src.piece_size - start_piece->used), length); + + ptr = start_piece->text + (startPos - start_first); + memmove(ptr + fill, ptr, (start_piece->used - + (startPos - start_first)) * sizeof(wchar_t)); + wptr =(wchar_t *)text.ptr; + (void)wcsncpy(ptr, wptr + firstPos, fill); + + startPos += fill; + firstPos += fill; + start_piece->used += fill; + length -= fill; + } + } + + if (local_artificial_block == True) + /* In other words, text is not the u_text that the user handed me but + one I made myself. I only care, because I need to free the string */ + XtFree(text.ptr); + + if (src->multi_src.use_string_in_place) + start_piece->text[start_piece->used] = (wchar_t)0; + +#ifdef OLDXAW + src->multi_src.changes = True; + XtCallCallbacks(w, XtNcallback, NULL); +#endif + + return (XawEditDone); +} + +/* + * Function: + * Scan + * + * Parameters: + * w - MultiSource widget + * position - position to start scanning + * type - type of thing to scan for + * dir - direction to scan + * count - which occurance if this thing to search for + * include - whether or not to include the character found in + * the position that is returned + * + * Description: + * Scans the text source for the number and type of item specified. + * + * Returns: + * The position of the item found + * + * Note: + * While there are only 'n' characters in the file there are n+1 + * possible cursor positions (one before the first character and + * one after the last character + */ +static XawTextPosition +Scan(Widget w, register XawTextPosition position, XawTextScanType type, + XawTextScanDirection dir, int count, Bool include) +{ + MultiSrcObject src = (MultiSrcObject)w; + register char inc; + MultiPiece *piece; + XawTextPosition first, first_eol_position = position; + register wchar_t *ptr; + int cnt = count; + + if (type == XawstAll) { + if (dir == XawsdRight) + return (src->multi_src.length); + return (0); + } + + /* STEP 1: basic sanity checks */ + if (position > src->multi_src.length) + position = src->multi_src.length; + + if (dir == XawsdRight) { + if (position == src->multi_src.length) + return (src->multi_src.length); + inc = 1; + } + else { + if (position == 0) + return (0); + inc = -1; + position--; + } + + piece = FindPiece(src, position, &first); + + if (piece->used == 0) + return (0); + + ptr = (position - first) + piece->text; + + switch (type) { + case XawstEOL: + case XawstParagraph: + case XawstWhiteSpace: + case XawstAlphaNumeric: + for (; cnt > 0 ; cnt--) { + Bool non_space = False, first_eol = True; + + /*CONSTCOND*/ + while (True) { + register wchar_t c; + + if (ptr < piece->text) { + piece = piece->prev; + if (piece == NULL) /* Begining of text */ + return (0); + ptr = piece->text + piece->used - 1; + c = *ptr; + } + else if (ptr >= piece->text + piece->used) { + piece = piece->next; + if (piece == NULL) /* End of text */ + return (src->multi_src.length); + ptr = piece->text; + } + + c = *ptr; + ptr += inc; + position += inc; + + if (type == XawstAlphaNumeric) { + if (!iswalnum(c)) { + if (non_space) + break; + } + else + non_space = True; + } + else if (type == XawstWhiteSpace) { + if (iswspace(c)) { + if (non_space) + break; + } + else + non_space = True; + } + else if (type == XawstEOL) { + if (c == _Xaw_atowc(XawLF)) + break; + } + else { /* XawstParagraph */ + if (first_eol) { + if (c == _Xaw_atowc(XawLF)) { + first_eol_position = position; + first_eol = False; + } + } + else + if (c == _Xaw_atowc(XawLF)) + break; + else if (!iswspace(c)) + first_eol = True; + } + } + } + if (!include) { + if (type == XawstParagraph) + position = first_eol_position; + if (count) + position -= inc; + } + break; + case XawstPositions: + position += count * inc; + break; + default: + break; + } + + if (dir == XawsdLeft) + position++; + + if (position >= src->multi_src.length) + return (src->multi_src.length); + if (position < 0) + return (0); + + return (position); +} + +/* + * Function: + * Search + * + * Parameters: + * w - MultiSource objecy + * position - position to start scanning + * dir - direction to scan + * text - text block to search for + * + * Description: + * Searchs the text source for the text block passed. + * + * Returns: + * The position of the item found + */ +static XawTextPosition +Search(Widget w, register XawTextPosition position, XawTextScanDirection dir, + XawTextBlock *text) +{ + MultiSrcObject src = (MultiSrcObject)w; + register int count = 0; + wchar_t *ptr; + wchar_t *wtarget; + int wtarget_len; + Display *d = XtDisplay(XtParent(w)); + MultiPiece *piece; + wchar_t *buf; + XawTextPosition first; + register char inc; + int cnt; + + /* STEP 1: First, a brief sanity check */ + if (dir == XawsdRight) + inc = 1; + else { + inc = -1; + if (position == 0) + return (XawTextSearchError); + position--; + } + + /* STEP 2: Ensure I have a local wide string.. */ + + /* Since this widget stores 32bit chars, I check here to see if + I'm being passed a string claiming to be 8bit chars (ie, MB text.) + If that is the case, naturally I convert to 32bit format */ + + /*if the block was FMT8BIT, length will convert to REAL wchar count bellow */ + wtarget_len = text->length; + + if (text->format == XawFmtWide) + wtarget = &(((wchar_t*)text->ptr) [text->firstPos]); + else { + /* The following converts wtarget_len from byte len to wchar count */ + wtarget = _XawTextMBToWC(d, &text->ptr[text->firstPos], &wtarget_len); + } + + /* OK, I can now assert that wtarget holds wide characters, wtarget_len + holds an accurate count of those characters, and that firstPos has been + effectively factored out of the following computations */ + + /* STEP 3: SEARCH! */ + buf = (wchar_t *)XtMalloc(sizeof(wchar_t) * wtarget_len); + (void)wcsncpy(buf, wtarget, wtarget_len); + piece = FindPiece(src, position, &first); + ptr = (position - first) + piece->text; + + /*CONSTCOND*/ + while (True) { + if (*ptr == (dir == XawsdRight ? *(buf + count) + : *(buf + wtarget_len - count - 1))) { + if (count == text->length - 1) + break; + else + count++; + } + else { + if (count != 0) { + position -=inc * count; + ptr -= inc * count; + } + count = 0; + } + + ptr += inc; + position += inc; + + while (ptr < piece->text) { + cnt = piece->text - ptr; + + piece = piece->prev; + if (piece == NULL) { /* Begining of text */ + XtFree((char *)buf); + return (XawTextSearchError); + } + ptr = piece->text + piece->used - cnt; + } + + while (ptr >= piece->text + piece->used) { + cnt = ptr - (piece->text + piece->used); + + piece = piece->next; + if (piece == NULL) { /* End of text */ + XtFree((char *)buf); + return (XawTextSearchError); + } + ptr = piece->text + cnt; + } + } + + XtFree((char *)buf); + if (dir == XawsdLeft) + return(position); + + return(position - (wtarget_len - 1)); +} + +/* + * Function: + * XawMultiSrcSetValues + * + * Parameters: + * current - current state of the widget + * request - what was requested + * cnew - what the widget will become + * args - representation of resources that have changed + * num_args - number of changed resources + * + * Description: + * Sets the values for the MultiSource. + * + * Returns: + * True if redisplay is needed + */ +static Boolean +XawMultiSrcSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + MultiSrcObject src = (MultiSrcObject)cnew; + MultiSrcObject old_src = (MultiSrcObject)current; + XtAppContext app_con = XtWidgetToApplicationContext(cnew); + Bool total_reset = False, string_set = False; + FILE *file; + unsigned int i; + + if (old_src->multi_src.use_string_in_place + != src->multi_src.use_string_in_place) { + XtAppWarning(app_con, + "MultiSrc: The XtNuseStringInPlace resources " + "may not be changed."); + src->multi_src.use_string_in_place = + old_src->multi_src.use_string_in_place; + } + + for (i = 0; i < *num_args ; i++) + if (streq(args[i].name, XtNstring)) { + string_set = True; + break; + } + + if (string_set || old_src->multi_src.type != src->multi_src.type) { + RemoveOldStringOrFile(old_src, string_set); + src->multi_src.allocated_string = old_src->multi_src.allocated_string; + file = InitStringOrFile(src, string_set); + + LoadPieces(src, file, NULL); + if (file != NULL) + fclose(file); +#ifndef OLDXAW + for (i = 0; i < src->text_src.num_text; i++) + /* Tell text widget what happened */ + XawTextSetSource(src->text_src.text[i], cnew, 0); +#else + XawTextSetSource(XtParent(cnew), cnew, 0); +#endif + total_reset = True; + } + + if (old_src->multi_src.multi_length != src->multi_src.multi_length) + src->multi_src.piece_size = src->multi_src.multi_length + 1; + + if ( !total_reset && old_src->multi_src.piece_size + != src->multi_src.piece_size) { + String mb_string = StorePiecesInString(old_src); + + if (mb_string != 0) { + FreeAllPieces(old_src); + LoadPieces(src, NULL, mb_string); + XtFree(mb_string); + } + else { + /* If the buffer holds bad chars, don't touch it... */ + XtAppWarningMsg(app_con, + "convertError", "multiSource", "XawError", + XtName(XtParent((Widget)old_src)), NULL, NULL); + XtAppWarningMsg(app_con, + "convertError", "multiSource", "XawError", + "Non-character code(s) in buffer.", NULL, NULL); + } + } + + return (False); +} + +static void +XawMultiSrcGetValuesHook(Widget w, ArgList args, Cardinal *num_args) +{ + MultiSrcObject src = (MultiSrcObject)w; + unsigned int i; + + if (src->multi_src.type == XawAsciiString) { + for (i = 0; i < *num_args ; i++) { + if (streq(args[i].name, XtNstring)) { + if (src->multi_src.use_string_in_place) + *((char **)args[i].value) = (char *) + src->multi_src.first_piece->text; + else if (_XawMultiSave(w)) /* If save sucessful */ + *((char **)args[i].value) = (char *)src->multi_src.string; + break; + } + } + } +} + +static void +XawMultiSrcDestroy(Widget w) +{ + RemoveOldStringOrFile((MultiSrcObject) w, True); +} + +/* + * Public routines + */ +/* + * Function: + * XawMultiSourceFreeString + * + * Parameters: + * w - MultiSrc widget + * + * Description: + * Frees the string returned by a get values call + * on the string when the source is of type string. + * + * Note: + * The public interface is XawAsciiSourceFreeString! + */ +void +_XawMultiSourceFreeString(Widget w) +{ + MultiSrcObject src = (MultiSrcObject)w; + + if (src->multi_src.allocated_string) { + XtFree((char *)src->multi_src.string); + src->multi_src.allocated_string = False; + src->multi_src.string = NULL; + } +} + +/* + * Function: + * _XawMultiSave + * + * Parameters: + * w - multiSrc Widget + * + * Description: + * Saves all the pieces into a file or string as required. + * + * Returns: + * True if the save was successful + * + * Note: + * The public interface is XawAsciiSave(w)! + */ +Bool +_XawMultiSave(Widget w) +{ + MultiSrcObject src = (MultiSrcObject)w; + XtAppContext app_con = XtWidgetToApplicationContext(w); + char *mb_string; + + /* + * If using the string in place then there is no need to play games + * to get the internal info into a readable string + */ + if (src->multi_src.use_string_in_place) + return (True); + + if (src->multi_src.type == XawAsciiFile) { +#ifdef OLDXAW + if (!src->multi_src.changes) +#else + if (!src->text_src.changed) /* No changes to save */ +#endif + return (True); + + mb_string = StorePiecesInString(src); + + if (mb_string != 0) { + if (WriteToFile(mb_string, (String)src->multi_src.string) == False) { + XtFree(mb_string); + return (False); + } + XtFree(mb_string); +#ifndef OLDXAW + src->text_src.changed = False; +#else + src->multi_src.changes = False; +#endif + return (True); + } + else { + /* If the buffer holds bad chars, don't touch it... */ + XtAppWarningMsg(app_con, + "convertError", "multiSource", "XawError", + "Due to illegal characters, file not saved.", + NULL, NULL); + return (False); + } + } + else { + /* THIS FUNCTIONALITY IS UNDOCUMENTED, probably UNNEEDED? The manual + says this routine's only function is to save files to + disk. -Sheeran */ + mb_string = StorePiecesInString(src); + + if (mb_string == 0) { + /* If the buffer holds bad chars, don't touch it... */ + XtAppWarningMsg(app_con, + "convertError", "multiSource", "XawError", + XtName(XtParent((Widget)src)), NULL, NULL); + return (False); + } + + /* assert: mb_string holds good characters so the buffer is fine */ + if (src->multi_src.allocated_string == True) + XtFree((char *)src->multi_src.string); + else + src->multi_src.allocated_string = True; + + src->multi_src.string = mb_string; + } +#ifdef OLDXAW + src->multi_src.changes = False; +#else + src->text_src.changed = False; +#endif + + return (True); +} + +/* + * Function: + * XawMultiSaveAsFile + * + * Parameters: + * w - MultiSrc widget + * name - name of the file to save this file into + * + * Description: + * Save the current buffer as a file. + * + * Returns: + * True if the save was sucessful + * + * Note: + * The public interface is XawAsciiSaveAsFile! + */ +Bool +_XawMultiSaveAsFile(Widget w, _Xconst char* name) +{ + MultiSrcObject src = (MultiSrcObject)w; + String mb_string; + Bool ret; + + mb_string = StorePiecesInString(src); + + if (mb_string != 0) { + ret = WriteToFile(mb_string, (char *)name); + XtFree(mb_string); + + return (ret); + } + + /* otherwise there was a conversion error. So print widget name too */ + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "convertError", "multiSource", "XawError", + XtName(XtParent(w)), NULL, NULL); + + return (False); +} + +/* + * Private Functions + */ +static void +RemoveOldStringOrFile(MultiSrcObject src, Bool checkString) +{ + FreeAllPieces(src); + + if (checkString && src->multi_src.allocated_string) { + XtFree((char *)src->multi_src.string); + src->multi_src.allocated_string = False; + src->multi_src.string = NULL; + } +} + +/* + * Function: + * WriteToFile + * + * Parameters: + * string - string to write + * name - name of the file + * + * Description: + * Write the string specified to the begining of the file specified. + * + * Returns: + * Returns True if sucessful, False otherwise + */ +static Bool +WriteToFile(String string, String name) +{ + int fd; + + if (((fd = creat(name, 0666)) == -1) + || (write(fd, string, strlen(string)) == -1)) + return (False); + + if (close(fd) == -1) + return (False); + + return (True); +} + + +/* + * Function: + * StorePiecesInString + * + * Parameters: + * src - the multiSrc object to gather data from + * + * Description: + * Store the pieces in memory into a char string. + * + * Returns: + * mb_string: Caller must free + * (or) + * NULL: conversion error + */ +static String +StorePiecesInString(MultiSrcObject src) +{ + wchar_t *wc_string; + char *mb_string; + int char_count = src->multi_src.length; + XawTextPosition first; + MultiPiece *piece; + + /* I believe the char_count + 1 and the NULL termination are unneeded! FS */ + wc_string = (wchar_t*)XtMalloc((char_count + 1) * sizeof(wchar_t)); + + for (first = 0, piece = src->multi_src.first_piece ; piece != NULL; + first += piece->used, piece = piece->next) + (void)wcsncpy(wc_string + first, piece->text, piece->used); + + wc_string[char_count] = 0; + + /* This will refill all pieces to capacity */ + if (src->multi_src.data_compression) { + FreeAllPieces(src); + LoadPieces(src, NULL, (char *)wc_string); + } + + /* Lastly, convert it to a MB format and send it back */ + mb_string = _XawTextWCToMB(XtDisplayOfObject((Widget)src), + wc_string, &char_count); + + /* NOTE THAT mb_string MAY BE ZERO IF THE CONVERSION FAILED */ + XtFree((char*)wc_string); + + return (mb_string); +} + +/* + * Function: + * InitStringOrFile + * + * Parameters: + * src - MultiSource + * + * Description: + * Initializes the string or file. + */ +static FILE * +InitStringOrFile(MultiSrcObject src, Bool newString) +{ + mode_t open_mode = 0; + const char *fdopen_mode = NULL; + int fd; + FILE *file; + Display *d = XtDisplayOfObject((Widget)src); + + if (src->multi_src.type == XawAsciiString) { + if (src->multi_src.string == NULL) + src->multi_src.length = 0; + + else if (!src->multi_src.use_string_in_place) { + int length; + String temp = XtNewString((char *)src->multi_src.string); + + if (src->multi_src.allocated_string) + XtFree((char *)src->multi_src.string); + src->multi_src.allocated_string = True; + src->multi_src.string = temp; + + length = strlen((char *)src->multi_src.string); + + /* Wasteful, throwing away the WC string, but need side effect! */ + (void)_XawTextMBToWC(d, (char *)src->multi_src.string, &length); + src->multi_src.length = (XawTextPosition)length; + } + else { + src->multi_src.length = strlen((char *)src->multi_src.string); + /* In case the length resource is incorrectly set */ + if (src->multi_src.length > src->multi_src.multi_length) + src->multi_src.multi_length = src->multi_src.length; + + if (src->multi_src.multi_length == MAGIC_VALUE) + src->multi_src.piece_size = src->multi_src.length; + else + src->multi_src.piece_size = src->multi_src.multi_length + 1; + } + + return (NULL); + } + + /* + * type is XawAsciiFile + */ + src->multi_src.is_tempfile = False; + + switch (src->text_src.edit_mode) { + case XawtextRead: + if (src->multi_src.string == NULL) + XtErrorMsg("NoFile", "multiSourceCreate", "XawError", + "Creating a read only disk widget and no file specified.", + NULL, 0); + open_mode = O_RDONLY; + fdopen_mode = "r"; + break; + case XawtextAppend: + case XawtextEdit: + if (src->multi_src.string == NULL) { + src->multi_src.string = "*multi-src*"; + src->multi_src.is_tempfile = True; + } + else { +/* O_NOFOLLOW is a BSD & Linux extension */ +#ifdef O_NOFOLLOW + open_mode = O_RDWR | O_NOFOLLOW; +#else + open_mode = O_RDWR; /* unsafe; subject to race conditions */ +#endif + fdopen_mode = "r+"; + } + break; + default: + XtErrorMsg("badMode", "multiSourceCreate", "XawError", + "Bad editMode for multi source; must be " + "Read, Append or Edit.", NULL, NULL); + } + + /* If is_tempfile, allocate a private copy of the text + * Unlikely to be changed, just to set allocated_string */ + if (newString || src->multi_src.is_tempfile) { + String temp = XtNewString((char *)src->multi_src.string); + + if (src->multi_src.allocated_string) + XtFree((char *)src->multi_src.string); + src->multi_src.string = temp; + src->multi_src.allocated_string = True; + } + + if (!src->multi_src.is_tempfile) { + if ((fd = open((char *)src->multi_src.string, open_mode, 0666)) != -1) { + if ((file = fdopen(fd, fdopen_mode)) != NULL) { + (void)fseek(file, 0, SEEK_END); + src->multi_src.length = (XawTextPosition)ftell(file); + return(file); + } + } + { + String params[2]; + Cardinal num_params = 2; + + params[0] = (String)src->multi_src.string; + params[1] = strerror(errno); + XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src), + "openError", "multiSourceCreate", "XawWarning", + "Cannot open file %s; %s", params, &num_params); + } + } + src->multi_src.length = 0; + return (NULL); +} + +/* LoadPieces: This routine takes either the MB contents of open file + `file' or the MB contents of string or the MB contents of + src->multi_src.string and places them in Pieces in WC format. + + CAUTION: You must have src->multi_src.length set to file length bytes + when src->multi_src.type == XawAsciiFile. src->multi_src.length must be + the length of the parameter string if string is non-NULL +*/ +static void +LoadPieces(MultiSrcObject src, FILE *file, char *string) +{ + Display *d = XtDisplayOfObject((Widget)src); + wchar_t* local_str, *ptr; + MultiPiece* piece = NULL; + XawTextPosition left; + int bytes = sizeof(wchar_t); + char* temp_mb_holder = NULL; + + /* + * This is tricky - the _XawTextMBtoWC converter uses its 3rd arg + * in as MB length, out as WC length. We want local_length to be + * WC count. + */ + int local_length = src->multi_src.length; + + if (string != NULL) { + /* + * ASSERT: IF our caller passed a non-null string, THEN + * src->multi_src.length is currently string's * byte count, + * AND string is in a MB format + */ + local_str = _XawTextMBToWC(d, (char *)string, &local_length); + src->multi_src.length = (XawTextPosition) local_length; + } + else if (src->multi_src.type != XawAsciiFile) { + /* + * here, we are not changing the contents, just reloading, + * so don't change len... + */ + local_length = src->multi_src.string ? + strlen((char *)src->multi_src.string) : 0; + local_str = _XawTextMBToWC(d, (char *)src->multi_src.string, + &local_length); + } + else { + if (src->multi_src.length != 0) { + temp_mb_holder = + XtMalloc((src->multi_src.length + 1) * sizeof(unsigned char)); + fseek(file, 0, 0); + src->multi_src.length = fread(temp_mb_holder, + (Size_t)sizeof(unsigned char), + (Size_t)src->multi_src.length, file); + if (src->multi_src.length <= 0) + XtAppErrorMsg(XtWidgetToApplicationContext ((Widget) src), + "readError", "multiSource", "XawError", + "fread returned error.", NULL, NULL); + local_length = src->multi_src.length; + local_str = _XawTextMBToWC(d, temp_mb_holder, &local_length); + src->multi_src.length = local_length; + + if (local_str == 0) { + String params[2]; + Cardinal num_params; + static char err_text[] = + "<<< FILE CONTENTS NOT REPRESENTABLE IN THIS LOCALE >>>"; + + params[0] = XtName(XtParent((Widget)src)); + params[1] = src->multi_src.string; + num_params = 2; + + XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src), + "readLocaleError", "multiSource", "XawError", + "%s: The file `%s' contains characters " + "not representable in this locale.", + params, &num_params); + src->multi_src.length = sizeof err_text; + local_length = src->multi_src.length; + local_str = _XawTextMBToWC(d, err_text, &local_length); + src->multi_src.length = local_length; + } + } + else + /* ASSERT that since following while loop looks at local_length + this isn't needed. Sheeran, Omron KK, 1993/07/15 + temp_mb_holder[src->multi_src.length] = '\0'; */ + local_str = (wchar_t*)temp_mb_holder; + } + + if (src->multi_src.use_string_in_place) { + piece = AllocNewPiece(src, piece); + piece->used = Min(src->multi_src.length, src->multi_src.piece_size); + piece->text = (wchar_t*)src->multi_src.string; + return; + } + + ptr = local_str; + left = local_length; + + do { + piece = AllocNewPiece(src, piece); + + piece->text = (wchar_t*)XtMalloc((unsigned)(src->multi_src.piece_size + * bytes)); + piece->used = Min(left, src->multi_src.piece_size); + if (piece->used != 0) + (void)wcsncpy(piece->text, ptr, piece->used); + + left -= piece->used; + ptr += piece->used; + } while (left > 0); + + if (temp_mb_holder) + XtFree((char*)temp_mb_holder); +} + +/* + * Function: + * AllocNewPiece + * + * Parameters: + * src - MultiSrc Widget + * prev - the piece just before this one, or NULL + * + * Description: + * Allocates a new piece of memory. + * + * Returns: + * The allocated piece + */ +static MultiPiece * +AllocNewPiece(MultiSrcObject src, MultiPiece *prev) +{ + MultiPiece *piece = XtNew(MultiPiece); + + if (prev == NULL) { + src->multi_src.first_piece = piece; + piece->next = NULL; + } + else { + if (prev->next != NULL) + (prev->next)->prev = piece; + piece->next = prev->next; + prev->next = piece; + } + + piece->prev = prev; + + return (piece); +} + +/* + * Function: + * FreeAllPieces + * + * Parameters: + * src - MultiSrc Widget + * + * Description: + * Frees all the pieces + */ +static void +FreeAllPieces(MultiSrcObject src) +{ + MultiPiece *next, *first = src->multi_src.first_piece; + +#ifdef DEBUG + if (first->prev != NULL) + printf("Xaw MultiSrc Object: possible memory leak in FreeAllPieces().\n"); +#endif + + for (; first != NULL ; first = next) { + next = first->next; + RemovePiece(src, first); + } +} + +/* + * Function: + * RemovePiece + * + * Parameters: + * piece - piece to remove + * + * Description: + * Removes a piece from the list. + */ +static void +RemovePiece(MultiSrcObject src, MultiPiece *piece) +{ + if (piece->prev == NULL) + src->multi_src.first_piece = piece->next; + else + piece->prev->next = piece->next; + + if (piece->next != NULL) + piece->next->prev = piece->prev; + + if (!src->multi_src.use_string_in_place) + XtFree((char *)piece->text); + + XtFree((char *)piece); +} + +/* + * Function: + * FindPiece + * + * Parameters: + * src - MultiSrc Widget + * position - position that we are searching for + * first - position of the first character in this piece (return) + * + * Description: + * Finds the piece containing the position indicated. + * + * Returns: + * Piece that contains this position + */ +static MultiPiece * +FindPiece(MultiSrcObject src, XawTextPosition position, XawTextPosition *first) +{ + MultiPiece *old_piece, *piece; + XawTextPosition temp; + + for (old_piece = NULL, piece = src->multi_src.first_piece, temp = 0; + piece; old_piece = piece, piece = piece->next) + if ((temp += piece->used) > position) { + *first = temp - piece->used; + return (piece); + } + + *first = temp - (old_piece ? old_piece->used : 0); + + return (old_piece); /* if we run off the end the return the last piece */ +} + +/* + * Function: + * BreakPiece + * + * Parameters: + * src - MultiSrc Widget + * piece - piece to break + * + * Description: + * Breaks a full piece into two new pieces. + */ +#define HALF_PIECE (src->multi_src.piece_size >> 1) +static void +BreakPiece(MultiSrcObject src, MultiPiece *piece) +{ + MultiPiece *cnew = AllocNewPiece(src, piece); + + cnew->text = (wchar_t *) + XtMalloc(src->multi_src.piece_size * sizeof(wchar_t)); + (void)wcsncpy(cnew->text, piece->text + HALF_PIECE, + src->multi_src.piece_size - HALF_PIECE); + piece->used = HALF_PIECE; + cnew->used = src->multi_src.piece_size - HALF_PIECE; +} + +/*ARGSUSED*/ +static void +CvtStringToMultiType(XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal) +{ + static XawAsciiType type = XawAsciiString; + XrmQuark q; + char name[7]; + + XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name)); + q = XrmStringToQuark(name); + + if (q == Qstring) + type = XawAsciiString; + if (q == Qfile) + type = XawAsciiFile; + else { + toVal->size = 0; + toVal->addr = NULL; + XtStringConversionWarning((char *)fromVal->addr, XtRAsciiType); + } + + toVal->size = sizeof(XawAsciiType); + toVal->addr = (XPointer)&type; +} + +/*ARGSUSED*/ +static Boolean +CvtMultiTypeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal, + XtPointer *data) +{ + static String buffer; + Cardinal size; + + switch (*(XawAsciiType *)fromVal->addr) { + case XawAsciiFile: + buffer = XtEfile; + break; + case XawAsciiString: + buffer = XtEstring; + break; + default: + XawTypeToStringWarning(dpy, XtRAsciiType); + toVal->addr = NULL; + toVal->size = 0; + return (False); + } + + size = strlen(buffer) + 1; + if (toVal->addr != NULL) { + if (toVal->size < size) { + toVal->size = size; + return (False); + } + strcpy((char *)toVal->addr, buffer); + } + else + toVal->addr = (XPointer)buffer; + toVal->size = sizeof(String); + + return (True); +} + +/*ARGSUSED*/ +static void +GetDefaultPieceSize(Widget w, int offset, XrmValue *value) +{ + static XPointer pagesize; + + if (pagesize == 0) { + pagesize = (XPointer)((long)_XawGetPageSize()); + if (pagesize < (XPointer)BUFSIZ) + pagesize = (XPointer)BUFSIZ; + } + + value->addr = (XPointer)&pagesize; +} diff --git a/src/OS.c b/src/OS.c new file mode 100644 index 0000000..8bc23dd --- /dev/null +++ b/src/OS.c @@ -0,0 +1,53 @@ +/* Some OS-dependent utility code */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include "Private.h" + +#ifndef X_NOT_POSIX +#include /* for sysconf(), and getpagesize() */ +#endif + +#if defined(linux) +/* kernel header doesn't work with -ansi */ +/* #include *//* for PAGE_SIZE */ +#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */ +#endif + +int +_XawGetPageSize(void) +{ + static int pagesize = -1; + + if (pagesize != -1) + return pagesize; + + /* Try each supported method in the preferred order */ + +#if defined(_SC_PAGESIZE) || defined(HAS_SC_PAGESIZE) + pagesize = sysconf(_SC_PAGESIZE); +#endif + +#ifdef _SC_PAGE_SIZE + if (pagesize == -1) + pagesize = sysconf(_SC_PAGE_SIZE); +#endif + +#ifdef HAVE_GETPAGESIZE + if (pagesize == -1) + pagesize = getpagesize(); +#endif + +#ifdef PAGE_SIZE + if (pagesize == -1) + pagesize = PAGE_SIZE; +#endif + + if (pagesize == -1) + pagesize = 0; + + return pagesize; +} diff --git a/src/Paned.c b/src/Paned.c new file mode 100644 index 0000000..26ff812 --- /dev/null +++ b/src/Paned.c @@ -0,0 +1,2063 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Updated and significantly modified from the Athena VPaned Widget. + * + * Date: March 1, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +typedef enum { + UpLeftPane = 'U', + LowRightPane = 'L', + ThisBorderOnly = 'T', + AnyPane = 'A' +} Direction; + +#define NO_INDEX -100 +#define IS_GRIP NULL + +#define PaneInfo(w) ((Pane)(w)->core.constraints) +#define HasGrip(w) (PaneInfo(w)->grip != NULL) +#define IsPane(w) ((w)->core.widget_class != gripWidgetClass) +#define PaneIndex(w) (PaneInfo(w)->position) +#define IsVert(w) ((w)->paned.orientation == XtorientVertical) + +#define ForAllPanes(pw, childP) \ +for ((childP) = (pw)->composite.children; \ + (childP) < (pw)->composite.children + (pw)->paned.num_panes; \ + (childP)++) + +#define ForAllChildren(pw, childP) \ +for ((childP) = (pw)->composite.children; \ + (childP) < (pw)->composite.children + (pw)->composite.num_children; \ + (childP)++) + +#define PaneSize(paned, vertical) \ + ((vertical) ? XtHeight(paned) : XtWidth(paned)) + +#define GetRequestInfo(geo, vertical) \ + ((vertical) ? (geo)->height : (geo)->width) + +#define SatisfiesRule1(pane, shrink) \ + (((shrink) && ((pane)->size != (pane)->min)) \ + || (!(shrink) && ((pane)->size != (pane)->max))) + +#define SatisfiesRule2(pane) \ + (!(pane)->skip_adjust || (pane)->paned_adjusted_me) + +#define SatisfiesRule3(pane, shrink) \ + ((pane)->paned_adjusted_me \ + && (((shrink) && ((int)(pane)->wp_size <= (pane)->size)) \ + || (!(shrink) && ((int)(pane)->wp_size >= (pane)->size)))) + + +/* + * Class Methods + */ +static void XawPanedClassInitialize(void); +static void XawPanedChangeManaged(Widget); +static void XawPanedDeleteChild(Widget); +static void XawPanedDestroy(Widget); +static XtGeometryResult XawPanedGeometryManager(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawPanedInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawPanedInsertChild(Widget); +static Boolean XawPanedPaneSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static void XawPanedRealize(Widget, Mask*, XSetWindowAttributes*); +static void XawPanedRedisplay(Widget, XEvent*, Region); +static void XawPanedResize(Widget); +static Boolean XawPanedSetValues(Widget, Widget, Widget, ArgList, Cardinal*); + +/* + * Prototypes + */ +static void _DrawInternalBorders(PanedWidget, GC); +static void _DrawRect(PanedWidget, GC, int, int, unsigned int, unsigned int); +static void _DrawTrackLines(PanedWidget, Bool); +static void AdjustPanedSize(PanedWidget, unsigned int, XtGeometryResult*, + Dimension*, Dimension*); +static void ChangeAllGripCursors(PanedWidget); +static Pane ChoosePaneToResize(PanedWidget, int, Direction, Bool); +static void ClearPaneStack(PanedWidget); +static void CommitGripAdjustment(PanedWidget); +static void CreateGrip(Widget); +static int GetEventLocation(PanedWidget, XEvent*); +static void GetGCs(Widget); +static void GetPaneStack(PanedWidget, Bool, Pane*, int*); +static void HandleGrip(Widget, XtPointer, XtPointer); +static void LoopAndRefigureChildren(PanedWidget, int, Direction, int*); +static void ManageAndUnmanageGrips(PanedWidget); +static void MoveGripAdjustment(PanedWidget, Widget, Direction, int); +static Bool PopPaneStack(PanedWidget); +static void PushPaneStack(PanedWidget, Pane); +static void RefigureLocations(PanedWidget, int, Direction); +static void RefigureLocationsAndCommit(Widget); +static void ReleaseGCs(Widget); +static void ResortChildren(PanedWidget); +static void SetChildrenPrefSizes(PanedWidget, unsigned int); +static void StartGripAdjustment(PanedWidget, Widget, Direction); + +/* + * Initialization + */ +static char defGripTranslations[] = +":" "GripAction(Start,UpLeftPane)\n" +":" "GripAction(Start,ThisBorderOnly)\n" +":" "GripAction(Start,LowRightPane)\n" +":" "GripAction(Move,UpLeft)\n" +":" "GripAction(Move,ThisBorder)\n" +":" "GripAction(Move,LowRight)\n" +"Any:" "GripAction(Commit)\n" +; + +#define offset(field) XtOffsetOf(PanedRec, paned.field) +static XtResource resources[] = { + { + XtNinternalBorderColor, + XtCBorderColor, + XtRPixel, + sizeof(Pixel), + offset(internal_bp), + XtRString, + (XtPointer)XtDefaultForeground + }, + { + XtNinternalBorderWidth, + XtCBorderWidth, + XtRDimension, + sizeof(Dimension), + offset(internal_bw), + XtRImmediate, + (XtPointer)1 + }, + { + XtNgripIndent, + XtCGripIndent, + XtRPosition, + sizeof(Position), + offset(grip_indent), + XtRImmediate, + (XtPointer)10 + }, + { + XtNrefigureMode, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(refiguremode), + XtRImmediate, + (XtPointer)True + }, + { + XtNgripTranslations, + XtCTranslations, + XtRTranslationTable, + sizeof(XtTranslations), + offset(grip_translations), + XtRString, + (XtPointer)defGripTranslations + }, + { + XtNorientation, + XtCOrientation, + XtROrientation, + sizeof(XtOrientation), + offset(orientation), + XtRImmediate, + (XtPointer)XtorientVertical + }, + { + XtNcursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(cursor), + XtRImmediate, + NULL + }, + { + XtNgripCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(grip_cursor), + XtRImmediate, + NULL + }, + { + XtNverticalGripCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(v_grip_cursor), + XtRString, + "sb_v_double_arrow" + }, + { + XtNhorizontalGripCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(h_grip_cursor), + XtRString, + "sb_h_double_arrow" + }, + { + XtNbetweenCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(adjust_this_cursor), + XtRString, + NULL + }, + { + XtNverticalBetweenCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(v_adjust_this_cursor), + XtRString, + "sb_left_arrow" + }, + { + XtNhorizontalBetweenCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(h_adjust_this_cursor), + XtRString, + "sb_up_arrow" + }, + { + XtNupperCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(adjust_upper_cursor), + XtRString, + "sb_up_arrow" + }, + { + XtNlowerCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(adjust_lower_cursor), + XtRString, + "sb_down_arrow" + }, + { + XtNleftCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(adjust_left_cursor), + XtRString, + "sb_left_arrow" + }, + { + XtNrightCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(adjust_right_cursor), + XtRString, + "sb_right_arrow" + }, +}; +#undef offset + +#define offset(field) XtOffsetOf(PanedConstraintsRec, paned.field) +static XtResource subresources[] = { + { + XtNallowResize, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(allow_resize), + XtRImmediate, + (XtPointer)False + }, + { + XtNposition, + XtCPosition, + XtRInt, + sizeof(int), + offset(position), + XtRImmediate, + (XtPointer)0 + }, + { + XtNmin, + XtCMin, + XtRDimension, + sizeof(Dimension), + offset(min), + XtRImmediate, + (XtPointer)PANED_GRIP_SIZE + }, + { + XtNmax, + XtCMax, + XtRDimension, + sizeof(Dimension), + offset(max), + XtRImmediate, + (XtPointer)~0 + }, + { + XtNpreferredPaneSize, + XtCPreferredPaneSize, + XtRDimension, + sizeof(Dimension), + offset(preferred_size), + XtRImmediate, + (XtPointer)PANED_ASK_CHILD + }, + { + XtNresizeToPreferred, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(resize_to_pref), + XtRImmediate, + (XtPointer)False + }, + { + XtNskipAdjust, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(skip_adjust), + XtRImmediate, + (XtPointer)False + }, + { + XtNshowGrip, + XtCShowGrip, + XtRBoolean, + sizeof(Boolean), + offset(show_grip), + XtRImmediate, + (XtPointer)True + }, +}; +#undef offset + +#define SuperClass ((ConstraintWidgetClass)&constraintClassRec) + +PanedClassRec panedClassRec = { + /* core */ + { + (WidgetClass)SuperClass, /* superclass */ + "Paned", /* class name */ + sizeof(PanedRec), /* size */ + XawPanedClassInitialize, /* class_initialize */ + NULL, /* class_part init */ + False, /* class_inited */ + XawPanedInitialize, /* initialize */ + NULL, /* initialize_hook */ + XawPanedRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawPanedDestroy, /* destroy */ + XawPanedResize, /* resize */ + XawPanedRedisplay, /* expose */ + XawPanedSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* composite */ + { + XawPanedGeometryManager, /* geometry_manager */ + XawPanedChangeManaged, /* change_managed */ + XawPanedInsertChild, /* insert_child */ + XawPanedDeleteChild, /* delete_child */ + NULL, /* extension */ + }, + /* constraint */ + { + subresources, /* subresources */ + XtNumber(subresources), /* subresource_count */ + sizeof(PanedConstraintsRec), /* constraint_size */ + NULL, /* initialize */ + NULL, /* destroy */ + XawPanedPaneSetValues, /* set_values */ + NULL, /* extension */ + }, +}; + +WidgetClass panedWidgetClass = (WidgetClass)&panedClassRec; +WidgetClass vPanedWidgetClass = (WidgetClass)&panedClassRec; + +/* + * Implementation + */ +/* Function: + * AdjustPanedSize + * + * Parameters: + * pw - paned widget to adjust + * off_size - new off_size to use + * result_ret - result of query (return) + * on_size_ret - new on_size (return) + * off_size_ret - new off_size (return) + * + * Description: + * Adjusts the size of the pane. + * + * Returns: + * amount of change in size + */ +static void +AdjustPanedSize(PanedWidget pw, unsigned int off_size, + XtGeometryResult *result_ret, + Dimension *on_size_ret, Dimension *off_size_ret) +{ + Dimension old_size = PaneSize((Widget)pw, IsVert(pw)); + Dimension newsize = 0; + Widget *childP; + XtWidgetGeometry request, reply; + + request.request_mode = CWWidth | CWHeight; + + ForAllPanes(pw, childP) { + int size = Max(PaneInfo(*childP)->size, (int)PaneInfo(*childP)->min); + + AssignMin(size, (int)PaneInfo(*childP)->max); + newsize += size + pw->paned.internal_bw; + } + newsize -= pw->paned.internal_bw; + + if (newsize < 1) + newsize = 1; + + if (IsVert(pw)) { + request.width = off_size; + request.height = newsize; + } + else { + request.width = newsize; + request.height = off_size; + } + + if (result_ret != NULL) { + request.request_mode |= XtCWQueryOnly; + + *result_ret = XtMakeGeometryRequest((Widget)pw, &request, &reply); + _XawImCallVendorShellExtResize((Widget)pw); + + if (newsize == old_size || *result_ret == XtGeometryNo) { + *on_size_ret = old_size; + *off_size_ret = off_size; + return; + } + if (*result_ret != XtGeometryAlmost) { + *on_size_ret = GetRequestInfo(&request, IsVert(pw)); + *off_size_ret = GetRequestInfo(&request, !IsVert(pw)); + return; + } + *on_size_ret = GetRequestInfo(&reply, IsVert(pw)); + *off_size_ret = GetRequestInfo(&reply, !IsVert(pw)); + return; + } + + if (newsize == old_size) + return; + + if (XtMakeGeometryRequest((Widget)pw, &request, &reply) == XtGeometryAlmost) + XtMakeGeometryRequest((Widget)pw, &reply, &request); +} + +/* + * Function: + * ChoosePaneToResize. + * + * Parameters: + * pw - paned widget + * paneindex - index of the current pane + * dir - direction to search first + * shrink - True if we need to shrink a pane, False otherwise + * + * Description: + * This function chooses a pane to resize. + * They are chosen using the following rules: + * + * 1) size < max && size > min + * 2) skip adjust == False + * 3) widget not its prefered height + * && this change will bring it closer + * && The user has not resized this pane. + * + * If no widgets are found that fits all the rules then + * rule #3 is broken. + * If there are still no widgets found than + * rule #2 is broken. + * Rule #1 is never broken. + * If no widgets are found then NULL is returned. + * + * Returns: + * pane to resize or NULL + */ +static Pane +ChoosePaneToResize(PanedWidget pw, int paneindex, Direction dir, Bool shrink) +{ + Widget *childP; + int rules = 3; + Direction _dir = dir; + int _index = paneindex; + + if (paneindex == NO_INDEX || dir == AnyPane) { /* Use defaults */ + _dir = LowRightPane; /* Go up - really */ + _index = pw->paned.num_panes - 1; /* Start the last pane, and work + backwards */ + } + childP = pw->composite.children + _index; + + /*CONSTCOND*/ + while(True) { + Pane pane = PaneInfo(*childP); + + if ((rules < 3 || SatisfiesRule3(pane, shrink)) + && (rules < 2 || SatisfiesRule2(pane)) + && SatisfiesRule1(pane, shrink) + && (paneindex != PaneIndex(*childP) || dir == AnyPane)) + return (pane); + + /* + * This is counter-intuitive, but if we are resizing the pane + * above the grip we want to choose a pane below the grip to lose, + * and visa-versa + */ + if (_dir == LowRightPane) + --childP; + else + ++childP; + + /* + * If we have come to and edge then reduce the rule set, and try again + * If we are reduced the rules to none, then return NULL + */ + if ((childP - pw->composite.children) < 0 || + (childP - pw->composite.children) >= pw->paned.num_panes) { + if (--rules < 1) /* less strict rules */ + return (NULL); + childP = pw->composite.children + _index; + } + } +} + +/* + * Function: + * LoopAndRefigureChildren + * + * Parameters: + * pw - paned widget + * paneindex - number of the pane border we are moving + * dir - pane to move (either UpLeftPane or LowRightPane) + * sizeused - current amount of space used (used and returned) + * + * Description: + * If we are resizing either the UpleftPane or LowRight Pane loop + * through all the children to see if any will allow us to resize them. + */ +static void +LoopAndRefigureChildren(PanedWidget pw, int paneindex, Direction dir, + int *sizeused) +{ + int pane_size = (int)PaneSize((Widget)pw, IsVert(pw)); + Boolean shrink = (*sizeused > pane_size); + + if (dir == LowRightPane) + paneindex++; + + /* While all panes do not fit properly */ + while (*sizeused != pane_size) { + /* + * Choose a pane to resize + * First look on the Pane Stack, and then go hunting for another one + * If we fail to find a pane to resize then give up + */ + Pane pane; + int start_size; + Dimension old; + Boolean rule3_ok = False, from_stack = True; + + GetPaneStack(pw, shrink, &pane, &start_size); + if (pane == NULL) { + pane = ChoosePaneToResize(pw, paneindex, dir, shrink); + if (pane == NULL) + return; /* no one to resize, give up */ + + rule3_ok = SatisfiesRule3(pane, shrink); + from_stack = False; + PushPaneStack(pw, pane); + } + + /* + * Try to resize this pane so that all panes will fit, take min and max + * into account + */ + old = pane->size; + pane->size += pane_size - *sizeused; + + if (from_stack) { + if (shrink) { + AssignMax(pane->size, start_size); + } /* don't remove these braces */ + else + AssignMin(pane->size, start_size); + + if (pane->size == start_size) + (void)PopPaneStack(pw); + } + else if (rule3_ok) { + if (shrink) { + AssignMax(pane->size, (int)pane->wp_size); + } /* don't remove these braces */ + else + AssignMin(pane->size, (int)pane->wp_size); + } + + pane->paned_adjusted_me = pane->size != pane->wp_size; + AssignMax(pane->size, (int)pane->min); + AssignMin(pane->size, (int)pane->max); + *sizeused += (pane->size - old); + } +} + +/* + * Function: + * RefigureLocations + * + * Parameters: + * pw - paned widget + * paneindex - child to start refiguring at + * dir - direction to move from child + * + * Description: + * Refigures all locations of children. + * There are special arguments to paneindex and dir, they are: + * paneindex - NO_INDEX. + * dir - AnyPane. + * + * If either of these is true then all panes may be resized and + * the choosing of panes procedes in reverse order starting with the + * last child. + */ +static void +RefigureLocations(PanedWidget pw, int paneindex, Direction dir) +{ + Widget *childP; + int pane_size = (int)PaneSize((Widget)pw, IsVert(pw)); + int sizeused = 0; + Position loc = 0; + + if (pw->paned.num_panes == 0 || !pw->paned.refiguremode) + return; + + /* + * Get an initial estimate of the size we will use + */ + ForAllPanes(pw, childP) { + Pane pane = PaneInfo(*childP); + + AssignMax(pane->size, (int) pane->min); + AssignMin(pane->size, (int) pane->max); + sizeused += (int)pane->size + (int)pw->paned.internal_bw; + } + sizeused -= (int)pw->paned.internal_bw; + + if (dir != ThisBorderOnly && sizeused != pane_size) + LoopAndRefigureChildren(pw, paneindex, dir, &sizeused); + + /* + * If we still are not the right size, then tell the pane that + * wanted to resize that it can't + */ + if (paneindex != NO_INDEX && dir != AnyPane) { + Pane pane = PaneInfo(*(pw->composite.children + paneindex)); + Dimension old = pane->size; + + pane->size += pane_size - sizeused; + AssignMax(pane->size, (int) pane->min); + AssignMin(pane->size, (int) pane->max); + sizeused += pane->size - old; + } + + /* + * It is possible that the panes will not fit inside the vpaned widget, but + * we have tried out best + * + * Assign each pane a location + */ + ForAllPanes(pw, childP) { + PaneInfo(*childP)->delta = loc; + loc += PaneInfo(*childP)->size + pw->paned.internal_bw; + } +} + +/* + * Function: + * CommitNewLocations + * + * Parameters: + * pw - paned widget + * + * Description: + * Commits all of the previously figured locations. + */ +static void +CommitNewLocations(PanedWidget pw) +{ + Widget *childP; + XWindowChanges changes; + + changes.stack_mode = Above; + + ForAllPanes(pw, childP) { + Pane pane = PaneInfo(*childP); + Widget grip = pane->grip; /* may be NULL */ + + if (IsVert(pw)) { + XtMoveWidget(*childP, (Position) 0, pane->delta); + XtResizeWidget(*childP, XtWidth(pw), pane->size, 0); + + if (HasGrip(*childP)) { /* Move and Display the Grip */ + changes.x = XtWidth(pw) - pw->paned.grip_indent - + XtWidth(grip) - (XtBorderWidth(grip) << 1); + changes.y = XtY(*childP) + XtHeight(*childP) - + (XtHeight(grip) >> 1) - XtBorderWidth(grip) + + (pw->paned.internal_bw >> 1); + } + } + else { + XtMoveWidget(*childP, pane->delta, 0); + XtResizeWidget(*childP, pane->size, XtHeight(pw), 0); + + if (HasGrip(*childP)) { /* Move and Display the Grip */ + changes.x = XtX(*childP) + XtWidth(*childP) - + (XtWidth(grip) >> 1) - XtBorderWidth(grip) + + (pw->paned.internal_bw >> 1); + changes.y = XtHeight(pw) - pw->paned.grip_indent - + XtHeight(grip) - (XtBorderWidth(grip) << 1); + } + } + + /* + * This should match XtMoveWidget, except that we're also insuring the + * grip is Raised in the same request + */ + + if (HasGrip(*childP)) { + XtX(grip) = changes.x; + XtY(grip) = changes.y; + + if (XtIsRealized(pane->grip)) + XConfigureWindow(XtDisplay(pane->grip), XtWindow(pane->grip), + CWX | CWY | CWStackMode, &changes); + } + } + ClearPaneStack(pw); +} + +/* + * Function: + * RefigureLocationsAndCommit + * + * Parameters: + * pw - paned widget + * + * Description: + * Refigures all locations in a paned widget and commits them immediately. + * + * This function does nothing if any of the following are true. + * o refiguremode is false. + * o The widget is unrealized. + * o There are no panes is the paned widget. + */ +static void +RefigureLocationsAndCommit(Widget w) +{ + PanedWidget pw = (PanedWidget)w; + + if (pw->paned.refiguremode && XtIsRealized(w) && pw->paned.num_panes > 0) { + RefigureLocations(pw, NO_INDEX, AnyPane); + CommitNewLocations(pw); + } +} + +/* + * Function: + * _DrawRect + * + * Parameters: + * pw - paned widget + * gc - gc to used for the draw + * on_olc - location of upper left corner of rect + * off_loc - "" + * on_size - size of rectangle + * off_size - "" + * + * Description: + * Draws a rectangle in the proper orientation. + */ +static void +_DrawRect(PanedWidget pw, GC gc, int on_loc, int off_loc, + unsigned int on_size, unsigned int off_size) +{ + if (IsVert(pw)) + XFillRectangle(XtDisplay((Widget)pw), XtWindow((Widget)pw), gc, + off_loc, on_loc, off_size, on_size); + else + XFillRectangle(XtDisplay((Widget)pw), XtWindow((Widget)pw), gc, + on_loc, off_loc, on_size, off_size); +} + +/* + * Function: + * _DrawInternalBorders + * + * Parameters: + * pw - paned widget + * gc - GC to use to draw the borders + * + * Description: + * Draws the internal borders into the paned widget. + */ +static void +_DrawInternalBorders(PanedWidget pw, GC gc) +{ + Widget *childP; + int on_loc, off_loc; + unsigned int on_size, off_size; + + /* + * This is an optimization. Do not paint the internal borders if + * they are the same color as the background + */ + if (pw->core.background_pixel == pw->paned.internal_bp) + return; + + off_loc = 0; + off_size = (unsigned int) PaneSize((Widget)pw, !IsVert(pw)); + on_size = (unsigned int)pw->paned.internal_bw; + + ForAllPanes(pw, childP) { + on_loc = IsVert(pw) ? XtY(*childP) : XtX(*childP); + on_loc -= (int)on_size; + + _DrawRect(pw, gc, on_loc, off_loc, on_size, off_size); + } +} + +#define DrawInternalBorders(pw) \ + _DrawInternalBorders((pw), (pw)->paned.normgc) +#define EraseInternalBorders(pw) \ + _DrawInternalBorders((pw), (pw)->paned.invgc) +/* + * Function Name: + * _DrawTrackLines + * + * Parameters: + * pw - Paned widget + * erase - if True then just erase track lines, else draw them in + * + * Description: + * Draws the lines that animate the pane borders when the grips are moved. + */ +static void +_DrawTrackLines(PanedWidget pw, Bool erase) +{ + Widget *childP; + Pane pane; + int on_loc, off_loc; + unsigned int on_size, off_size; + + off_loc = 0; + off_size = PaneSize((Widget)pw, !IsVert(pw)); + + ForAllPanes(pw, childP) { + pane = PaneInfo(*childP); + if (erase || pane->olddelta != pane->delta) { + on_size = pw->paned.internal_bw; + if (!erase) { + on_loc = PaneInfo(*childP)->olddelta - (int) on_size; + _DrawRect(pw, pw->paned.flipgc, + on_loc, off_loc, on_size, off_size); + } + + on_loc = PaneInfo(*childP)->delta - (int)on_size; + + _DrawRect(pw, pw->paned.flipgc, + on_loc, off_loc, on_size, off_size); + + pane->olddelta = pane->delta; + } + } +} + +#define DrawTrackLines(pw) _DrawTrackLines((pw), False); +#define EraseTrackLines(pw) _DrawTrackLines((pw), True); +/* + * Function: + * GetEventLocation + * + * Parameters: + * pw - the paned widget + * event - pointer to an event + * + * Description: + * Converts and event to an x and y location. + * + * Returns: + * if this is a vertical pane then (y) else (x) + */ +static int +GetEventLocation(PanedWidget pw, XEvent *event) +{ + int x, y; + + switch (event->xany.type) { + case ButtonPress: + case ButtonRelease: + x = event->xbutton.x_root; + y = event->xbutton.y_root; + break; + case KeyPress: + case KeyRelease: + x = event->xkey.x_root; + y = event->xkey.y_root; + break; + case MotionNotify: + x = event->xmotion.x_root; + y = event->xmotion.y_root; + break; + default: + x = pw->paned.start_loc; + y = pw->paned.start_loc; + } + + if (IsVert(pw)) + return (y); + + return (x); +} + +/* + * Function: + * StartGripAdjustment + * + * Parameters: + * pw - paned widget + * grip - grip widget selected + * dir - direction that we are to be moving + * + * Description: + * Starts the grip adjustment procedure. + */ +static void +StartGripAdjustment(PanedWidget pw, Widget grip, Direction dir) +{ + Widget *childP; + Cursor cursor; + + pw->paned.whichadd = pw->paned.whichsub = NULL; + + if (dir == ThisBorderOnly || dir == UpLeftPane) + pw->paned.whichadd = pw->composite.children[PaneIndex(grip)]; + if (dir == ThisBorderOnly || dir == LowRightPane) + pw->paned.whichsub = pw->composite.children[PaneIndex(grip) + 1]; + + /* + * Change the cursor + */ + if (XtIsRealized(grip)) { + if (IsVert(pw)) { + if (dir == UpLeftPane) + cursor = pw->paned.adjust_upper_cursor; + else if (dir == LowRightPane) + cursor = pw->paned.adjust_lower_cursor; + else { + if (pw->paned.adjust_this_cursor == None) + cursor = pw->paned.v_adjust_this_cursor; + else + cursor = pw->paned.adjust_this_cursor; + } + } + else { + if (dir == UpLeftPane) + cursor = pw->paned.adjust_left_cursor; + else if (dir == LowRightPane) + cursor = pw->paned.adjust_right_cursor; + else { + if (pw->paned.adjust_this_cursor == None) + cursor = pw->paned.h_adjust_this_cursor; + else + cursor = pw->paned.adjust_this_cursor; + } + } + + XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor); + } + + EraseInternalBorders(pw); + ForAllPanes(pw, childP) + PaneInfo(*childP)->olddelta = -99; + + EraseTrackLines(pw); +} + +/* + * Function: + * MoveGripAdjustment + * + * Parameters: + * pw - paned widget + * grip - grip that we are moving + * dir - direction the pane we are interested is w.r.t the grip + * loc - location of pointer in proper direction + * + * Description: + * This routine moves all panes around when a grip is moved. + */ +static void +MoveGripAdjustment(PanedWidget pw, Widget grip, Direction dir, int loc) +{ + int diff, add_size = 0, sub_size = 0; + + diff = loc - pw->paned.start_loc; + + if (pw->paned.whichadd) + add_size = PaneSize(pw->paned.whichadd, IsVert(pw)) + diff; + + if (pw->paned.whichsub) + sub_size = PaneSize(pw->paned.whichsub, IsVert(pw)) - diff; + + /* + * If moving this border only then do not allow either of the borders + * to go beyond the min or max size allowed + */ + if (dir == ThisBorderOnly) { + int old_add_size = add_size, old_sub_size; + + AssignMax(add_size, (int)PaneInfo(pw->paned.whichadd)->min); + AssignMin(add_size, (int)PaneInfo(pw->paned.whichadd)->max); + if (add_size != old_add_size) + sub_size += old_add_size - add_size; + + old_sub_size = sub_size; + AssignMax(sub_size, (int)PaneInfo(pw->paned.whichsub)->min); + AssignMin(sub_size, (int)PaneInfo(pw->paned.whichsub)->max); + if (sub_size != old_sub_size) + return; /* Abort to current sizes */ + } + + if (add_size != 0) + PaneInfo(pw->paned.whichadd)->size = add_size; + if (sub_size != 0) + PaneInfo(pw->paned.whichsub)->size = sub_size; + RefigureLocations(pw, PaneIndex(grip), dir); + DrawTrackLines(pw); +} + +/* + * Function: + * CommitGripAdjustment + * + * Parameters: + * pw - paned widget + * + * Description: + * Commits the grip adjustment. + */ +static void +CommitGripAdjustment(PanedWidget pw) +{ + EraseTrackLines(pw); + CommitNewLocations(pw); + DrawInternalBorders(pw); + + /* + * Since the user selected this size then use it as the preferred size + */ + if (pw->paned.whichadd) { + Pane pane = PaneInfo(pw->paned.whichadd); + + pane->wp_size = pane->size; + } + if (pw->paned.whichsub) { + Pane pane = PaneInfo(pw->paned.whichsub); + + pane->wp_size = pane->size; + } +} + +/* + * Function: + * HandleGrip + * + * Parameters: + * grip - grip widget that has been moved + * temp - (not used) + * call_data - data passed to us from the grip widget + * + * Description: + * Handles the grip manipulations. + */ +/*ARGSUSED*/ +static void +HandleGrip(Widget grip, XtPointer temp, XtPointer callData) +{ + XawGripCallData call_data = (XawGripCallData)callData; + PanedWidget pw = (PanedWidget) XtParent(grip); + int loc; + char action_type[2], direction[2]; + Cursor cursor; + Arg arglist[1]; + + if (call_data->num_params) + XmuNCopyISOLatin1Uppered(action_type, call_data->params[0], + sizeof(action_type)); + + if (call_data->num_params == 0 + || (action_type[0] == 'C' && call_data->num_params != 1) + || (action_type[0] != 'C' && call_data->num_params != 2)) + XtAppError(XtWidgetToApplicationContext(grip), + "Paned GripAction has been passed incorrect parameters."); + + loc = GetEventLocation(pw, (XEvent *)call_data->event); + + if (action_type[0] != 'C') + XmuNCopyISOLatin1Uppered(direction, call_data->params[1], + sizeof(direction)); + + switch (action_type[0]) { + case 'S': /* Start adjustment */ + pw->paned.resize_children_to_pref = False; + StartGripAdjustment(pw, grip, (Direction)direction[0]); + pw->paned.start_loc = loc; + break; + case 'M': + MoveGripAdjustment(pw, grip, (Direction)direction[0], loc); + break; + case 'C': + XtSetArg(arglist[0], XtNcursor, &cursor); + XtGetValues(grip, arglist, 1); + XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor); + CommitGripAdjustment(pw); + break; + default: + XtAppError(XtWidgetToApplicationContext(grip), + "Paned GripAction(); 1st parameter invalid"); + break; + } +} + +/* + * Function: + * ResortChildren + * + * Arguments: + * pw - paned widget + * + * Description: + * Resorts the children so that all managed children are first. + */ +static void +ResortChildren(PanedWidget pw) +{ + Widget *unmanagedP, *childP; + + unmanagedP = NULL; + ForAllChildren(pw, childP) { + if (!IsPane(*childP) || !XtIsManaged(*childP)) { + /* + * We only keep track of the first unmanaged pane + */ + if (unmanagedP == NULL) + unmanagedP = childP; + } + else { /* must be a managed pane */ + /* + * If an earlier widget was not a managed pane, then swap + */ + if (unmanagedP != NULL) { + Widget child = *unmanagedP; + + *unmanagedP = *childP; + *childP = child; + childP = unmanagedP; /* easiest to just back-track */ + unmanagedP = NULL; /* in case there is another managed */ + } + } + } +} + +/* + * Function: + * ManageAndUnmanageGrips + * + * Parameters: + * pw - paned widget + * + * Description: + * This function manages and unmanages the grips so that + * the managed state of each grip matches that of its pane. + */ +static void +ManageAndUnmanageGrips(PanedWidget pw) +{ + WidgetList managed_grips, unmanaged_grips; + Widget *managedP, *unmanagedP, *childP; + Cardinal alloc_size; + + alloc_size = sizeof(Widget) * (pw->composite.num_children >> 1); + managedP = managed_grips = (WidgetList)XtMalloc(alloc_size); + unmanagedP = unmanaged_grips = (WidgetList)XtMalloc(alloc_size); + + ForAllChildren(pw, childP) + if (IsPane(*childP) && HasGrip(*childP)) { + if (XtIsManaged(*childP)) + *managedP++ = PaneInfo(*childP)->grip; + else + *unmanagedP++ = PaneInfo(*childP)->grip; + } + + if (managedP != managed_grips) { + *unmanagedP++ = *--managedP; /* Last grip is never managed */ + XtManageChildren(managed_grips, managedP - managed_grips); + } + + if (unmanagedP != unmanaged_grips) + XtUnmanageChildren(unmanaged_grips, unmanagedP - unmanaged_grips); + + XtFree((char *)managed_grips); + XtFree((char *)unmanaged_grips); +} + +/* + * Function: + * CreateGrip + * + * Parameters: + * child - child that wants a grip to be created for it + * + * Description: + * Creates a grip widget. + */ +static void +CreateGrip(Widget child) +{ + PanedWidget pw = (PanedWidget)XtParent(child); + Arg arglist[2]; + Cardinal num_args = 0; + Cursor cursor; + + XtSetArg(arglist[num_args], XtNtranslations, pw->paned.grip_translations); + num_args++; + if ((cursor = pw->paned.grip_cursor) == None) { + if (IsVert(pw)) + cursor = pw->paned.v_grip_cursor; + else + cursor = pw->paned.h_grip_cursor; + } + + XtSetArg(arglist[num_args], XtNcursor, cursor); + num_args++; + PaneInfo(child)->grip = XtCreateWidget("grip", gripWidgetClass, (Widget)pw, + arglist, num_args); + + XtAddCallback(PaneInfo(child)->grip, XtNcallback, + HandleGrip, (XtPointer)child); +} + +/* + * Function: + * GetGCs + * + * Parameters: + * w - paned widget + */ +static void +GetGCs(Widget w) +{ + PanedWidget pw = (PanedWidget)w; + XtGCMask valuemask; + XGCValues values; + + /* + * Draw pane borders in internal border color + */ + values.foreground = pw->paned.internal_bp; + valuemask = GCForeground; + pw->paned.normgc = XtGetGC(w, valuemask, &values); + + /* + * Erase pane borders with background color + */ + values.foreground = pw->core.background_pixel; + valuemask = GCForeground; + pw->paned.invgc = XtGetGC(w, valuemask, &values); + + /* + * Draw Track lines (animate pane borders) in + * internal border color ^ bg color + */ + values.function = GXinvert; + values.plane_mask = pw->paned.internal_bp ^ pw->core.background_pixel; + values.subwindow_mode = IncludeInferiors; + valuemask = GCPlaneMask | GCFunction | GCSubwindowMode; + pw->paned.flipgc = XtGetGC(w, valuemask, &values); +} + +/* + * Function: + * SetChildrenPrefSizes + * + * Parameters: + * pw - paned widget + * + * Description: + * Sets the preferred sizes of the children. + */ +static void +SetChildrenPrefSizes(PanedWidget pw, unsigned int off_size) +{ + Widget *childP; + Boolean vert = IsVert(pw); + XtWidgetGeometry request, reply; + + ForAllPanes(pw, childP) + if (pw->paned.resize_children_to_pref || PaneInfo(*childP)->size == 0 || + PaneInfo(*childP)->resize_to_pref) { + if (PaneInfo(*childP)->preferred_size != PANED_ASK_CHILD) + PaneInfo(*childP)->wp_size = PaneInfo(*childP)->preferred_size; + else { + if(vert) { + request.request_mode = CWWidth; + request.width = off_size; + } + else { + request.request_mode = CWHeight; + request.height = off_size; + } + + if ((XtQueryGeometry(*childP, &request, &reply) + == XtGeometryAlmost) + && (reply.request_mode = (vert ? CWHeight : CWWidth))) + PaneInfo(*childP)->wp_size = GetRequestInfo(&reply, vert); + else + PaneInfo(*childP)->wp_size = PaneSize(*childP, vert); + } + + PaneInfo(*childP)->size = PaneInfo(*childP)->wp_size; + } +} + +/* + * Function: + * ChangeAllGripCursors + * + * Parameters: + * pw - paned widget + * + * Description: + * Changes all the grip cursors. + */ +static void +ChangeAllGripCursors(PanedWidget pw) +{ + Widget *childP; + + ForAllPanes(pw, childP) { + Arg arglist[1]; + Cursor cursor; + + if ((cursor = pw->paned.grip_cursor) == None) { + if (IsVert(pw)) + cursor = pw->paned.v_grip_cursor; + else + cursor = pw->paned.h_grip_cursor; + } + + if (HasGrip(*childP)) { + XtSetArg(arglist[0], XtNcursor, cursor); + XtSetValues(PaneInfo(*childP)->grip, arglist, 1); + } + } +} + +/* + * Function: + * PushPaneStack + * + * Parameters: + * pw - paned widget + * pane - pane that we are pushing + * + * Description: + * Pushes a value onto the pane stack. + */ +static void +PushPaneStack(PanedWidget pw, Pane pane) +{ + PaneStack *stack = (PaneStack *)XtMalloc(sizeof(PaneStack)); + + stack->next = pw->paned.stack; + stack->pane = pane; + stack->start_size = pane->size; + + pw->paned.stack = stack; +} + +/* + * Function: + * GetPaneStack + * + * Parameters: + * pw - paned widget + * shrink - True if we want to shrink this pane, False otherwise + * pane - pane that we are popping (return) + * start_size - size that this pane started at (return) + * + * Description: + * Gets the top value from the pane stack. + */ +static void +GetPaneStack(PanedWidget pw, Bool shrink, Pane *pane, int *start_size) +{ + if (pw->paned.stack == NULL) { + *pane = NULL; + return; + } + + *pane = pw->paned.stack->pane; + *start_size = pw->paned.stack->start_size; + + if (shrink != ((*pane)->size > *start_size)) + *pane = NULL; +} + +/* + * Function: + * PopPaneStack + * + * Parameters: + * pw - paned widget + * + * Description: + * Pops the top item off the pane stack. + * + * Returns: True if this is not the last element on the stack + */ +static Bool +PopPaneStack(PanedWidget pw) +{ + PaneStack *stack = pw->paned.stack; + + if (stack == NULL) + return (False); + + pw->paned.stack = stack->next; + XtFree((char *)stack); + + if (pw->paned.stack == NULL) + return (False); + + return (True); +} + +/* + * Function: + * ClearPaneStack + * + * Parameters: + * pw - paned widget + * + * Description: + * Removes all entries from the pane stack. + */ +static void +ClearPaneStack(PanedWidget pw) +{ + while(PopPaneStack(pw)) + ; +} + +static void +XawPanedClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtAddConverter(XtRString, XtROrientation, XmuCvtStringToOrientation, + NULL, 0); + XtSetTypeConverter(XtROrientation, XtRString, XmuCvtOrientationToString, + NULL, 0, XtCacheNone, NULL); +} + +/* The Geometry Manager only allows changes after Realize if + * allow_resize is True in the constraints record. + * + * For vertically paned widgets: + * + * It only allows height changes, but offers the requested height + * as a compromise if both width and height changes were requested. + * + * For horizontal widgets the converse is true. + * As all good Geometry Managers should, we will return No if the + * request will have no effect; i.e. when the requestor is already + * of the desired geometry. + */ +static XtGeometryResult +XawPanedGeometryManager(Widget w, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + PanedWidget pw = (PanedWidget)XtParent(w); + XtGeometryMask mask = request->request_mode; + Dimension old_size, old_wpsize, old_paned_size; + Pane pane = PaneInfo(w); + Boolean vert = IsVert(pw); + Dimension on_size, off_size; + XtGeometryResult result; + Boolean almost = False; + + /* + * If any of the following is true, disallow the geometry change + * + * o The paned widget is realized and allow_resize is false for the pane + * o The child did not ask to change the on_size + * o The request is not a width or height request + * o The requested size is the same as the current size + */ + + if ((XtIsRealized((Widget)pw) && !pane->allow_resize) + || !(mask & (vert ? CWHeight : CWWidth)) + ||(mask & ~(CWWidth | CWHeight)) + || GetRequestInfo(request, vert) == PaneSize(w, vert)) + return (XtGeometryNo); + + old_paned_size = PaneSize((Widget)pw, vert); + old_wpsize = pane->wp_size; + old_size = pane->size; + + pane->wp_size = pane->size = GetRequestInfo(request, vert); + + AdjustPanedSize(pw, PaneSize((Widget)pw, !vert), &result, &on_size, + &off_size); + + /* + * Fool the Refigure Locations proc to thinking that we are + * a different on_size + */ + + if (result != XtGeometryNo) { + if (vert) + XtHeight(pw) = on_size; + else + XtWidth(pw) = on_size; + } + + RefigureLocations(pw, PaneIndex(w), AnyPane); + + /* + * Set up reply struct and reset core on_size + */ + if (vert) { + XtHeight(pw) = old_paned_size; + reply->height = pane->size; + reply->width = off_size; + } + else { + XtWidth(pw) = old_paned_size; + reply->height = off_size; + reply->width = pane->size; + } + + /* + * IF either of the following is true + * + * o There was a "off_size" request and the new "off_size" is different + * from that requested + * o There was no "off_size" request and the new "off_size" is different + * + * o The "on_size" we will allow is different from that requested + * + * THEN: set almost + */ + if (!((vert ? CWWidth : CWHeight) & mask)) { + if (vert) + request->width = XtWidth(w); + else + request->height = XtHeight(w); + } + + almost = GetRequestInfo(request, !vert) != GetRequestInfo(reply, !vert); + almost |= (GetRequestInfo(request, vert) != GetRequestInfo(reply, vert)); + + if ((mask & XtCWQueryOnly) || almost) { + pane->wp_size = old_wpsize; + pane->size = old_size; + RefigureLocations(pw, PaneIndex(w), AnyPane); + reply->request_mode = CWWidth | CWHeight; + if (almost) + return (XtGeometryAlmost); + } + else { + AdjustPanedSize(pw, PaneSize((Widget) pw, !vert), NULL, NULL, NULL); + CommitNewLocations(pw); /* layout already refigured */ + } + + return (XtGeometryDone); +} + +/*ARGSUSED*/ +static void +XawPanedInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + PanedWidget pw = (PanedWidget)cnew; + + GetGCs((Widget)pw); + + pw->paned.recursively_called = False; + pw->paned.stack = NULL; + pw->paned.resize_children_to_pref = True; + pw->paned.num_panes = 0; +} + +static void +XawPanedRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) +{ + PanedWidget pw = (PanedWidget)w; + Widget *childP; + + if ((attributes->cursor = pw->paned.cursor) != None) + *valueMask |= CWCursor; + + (*SuperClass->core_class.realize)(w, valueMask, attributes); + + /* + * Before we commit the new locations we need to realize all the panes and + * their grips + */ + ForAllPanes(pw, childP) { + XtRealizeWidget(*childP); + if (HasGrip(*childP)) + XtRealizeWidget(PaneInfo(*childP)->grip); + } + + RefigureLocationsAndCommit(w); + pw->paned.resize_children_to_pref = False; +} + +static void +XawPanedDestroy(Widget w) +{ + ReleaseGCs(w); +} + +static void +ReleaseGCs(Widget w) +{ + PanedWidget pw = (PanedWidget)w; + + XtReleaseGC(w, pw->paned.normgc); + XtReleaseGC(w, pw->paned.invgc); + XtReleaseGC(w, pw->paned.flipgc); +} + +static void +XawPanedInsertChild(Widget w) +{ + Pane pane = PaneInfo(w); + + /* insert the child widget in the composite children list with the + superclass insert_child routine + */ + (*SuperClass->composite_class.insert_child)(w); + + if (!IsPane(w)) + return; + + if (pane->show_grip == True) { + CreateGrip(w); + if (pane->min == PANED_GRIP_SIZE) + pane->min = PaneSize(pane->grip, IsVert((PanedWidget)XtParent(w))); + } + else { + if (pane->min == PANED_GRIP_SIZE) + pane->min = 1; + pane->grip = NULL; + } + + pane->size = 0; + pane->paned_adjusted_me = False; +} + +static void +XawPanedDeleteChild(Widget w) +{ + /* remove the subwidget info and destroy the grip */ + if (IsPane(w) && HasGrip(w)) + XtDestroyWidget(PaneInfo(w)->grip); + + /* delete the child widget in the composite children list with the + superclass delete_child routine + */ + (*SuperClass->composite_class.delete_child)(w); +} + +static void +XawPanedChangeManaged(Widget w) +{ + PanedWidget pw = (PanedWidget)w; + Boolean vert = IsVert(pw); + Dimension size; + Widget *childP; + + if (pw->paned.recursively_called++) + return; + + /* + * If the size is zero then set it to the size of the widest or tallest pane + */ + + if ((size = PaneSize((Widget)pw, !vert)) == 0) { + size = 1; + ForAllChildren(pw, childP) + if (XtIsManaged(*childP) && (PaneSize(*childP, !vert) > size)) + size = PaneSize(*childP, !vert); + } + + ManageAndUnmanageGrips(pw); + pw->paned.recursively_called = False; + ResortChildren(pw); + + pw->paned.num_panes = 0; + ForAllChildren(pw, childP) + if (IsPane(*childP)) { + if (XtIsManaged(*childP)) { + Pane pane = PaneInfo(*childP); + + if (HasGrip(*childP)) + PaneInfo(pane->grip)->position = pw->paned.num_panes; + pane->position = pw->paned.num_panes; /* TEMPORY -CDP 3/89 */ + pw->paned.num_panes++; + } + else + break; /* This list is already sorted */ + } + + SetChildrenPrefSizes((PanedWidget) w, size); + + /* + * ForAllPanes can now be used + */ + if (PaneSize((Widget) pw, vert) == 0) + AdjustPanedSize(pw, size, NULL, NULL, NULL); + + if (XtIsRealized((Widget)pw)) + RefigureLocationsAndCommit((Widget)pw); +} + +static void +XawPanedResize(Widget w) +{ + SetChildrenPrefSizes((PanedWidget)w, + PaneSize(w, !IsVert((PanedWidget)w))); + RefigureLocationsAndCommit(w); +} + +/*ARGSUSED*/ +static void +XawPanedRedisplay(Widget w, XEvent *event, Region region) +{ + DrawInternalBorders((PanedWidget)w); +} + +/*ARGSUSED*/ +static Boolean +XawPanedSetValues(Widget old, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + PanedWidget old_pw = (PanedWidget)old; + PanedWidget new_pw = (PanedWidget)cnew; + Boolean redisplay = False; + + if ((old_pw->paned.cursor != new_pw->paned.cursor) && XtIsRealized(cnew)) + XDefineCursor(XtDisplay(cnew), XtWindow(cnew), new_pw->paned.cursor); + + if (old_pw->paned.internal_bp != new_pw->paned.internal_bp || + old_pw->core.background_pixel != new_pw->core.background_pixel) { + ReleaseGCs(old); + GetGCs(cnew); + redisplay = True; + } + + if (old_pw->paned.grip_cursor != new_pw->paned.grip_cursor || + old_pw->paned.v_grip_cursor != new_pw->paned.v_grip_cursor || + old_pw->paned.h_grip_cursor != new_pw->paned.h_grip_cursor) + ChangeAllGripCursors(new_pw); + + if (IsVert(old_pw) != IsVert(new_pw)) { + /* + * We are fooling the paned widget into thinking that is needs to + * fully refigure everything, which is what we want + */ + if (IsVert(new_pw)) + XtWidth(new_pw) = 0; + else + XtHeight(new_pw) = 0; + + new_pw->paned.resize_children_to_pref = True; + XawPanedChangeManaged(cnew); /* Seems weird, but does the right thing */ + new_pw->paned.resize_children_to_pref = False; + if (new_pw->paned.grip_cursor == None) + ChangeAllGripCursors(new_pw); + return (True); + } + + if (old_pw->paned.internal_bw != new_pw->paned.internal_bw) { + AdjustPanedSize(new_pw, PaneSize(cnew, !IsVert(old_pw)), + NULL, NULL, NULL); + RefigureLocationsAndCommit(cnew); + return (True); /* We have done a full configuration, return */ + } + + if (old_pw->paned.grip_indent != new_pw->paned.grip_indent && + XtIsRealized(cnew)) { + CommitNewLocations(new_pw); + redisplay = True; + } + + return (redisplay); +} + +/*ARGSUSED*/ +static Boolean +XawPanedPaneSetValues(Widget old, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + Pane old_pane = PaneInfo(old); + Pane new_pane = PaneInfo(cnew); + Boolean redisplay = False; + + /* Check for new min and max */ + if (old_pane->min != new_pane->min || old_pane->max != new_pane->max) + XawPanedSetMinMax(cnew, (int)new_pane->min, (int)new_pane->max); + + /* Check for change in XtNshowGrip */ + if (old_pane->show_grip != new_pane->show_grip) { + if (new_pane->show_grip == True) { + CreateGrip(cnew); + if (XtIsRealized(XtParent(cnew))) { + if (XtIsManaged(cnew)) /* if paned is unrealized this will + happen automatically at realize time + */ + XtManageChild(PaneInfo(cnew)->grip); /* manage the grip */ + XtRealizeWidget(PaneInfo(cnew)->grip); /* realize the grip */ + CommitNewLocations((PanedWidget)XtParent(cnew)); + } + } + else if (HasGrip(old)) { + XtDestroyWidget(old_pane->grip); + new_pane->grip = NULL; + redisplay = True; + } + } + + return (redisplay); +} + +/* + * Public routines + */ +/* + * Function: + * XawPanedSetMinMax + * + * Parameters: + * widget - widget that is a child of the Paned widget + * min - new min and max size for the pane + * max - "" + * + * Description: + * Sets the min and max size for a pane. + */ +void +XawPanedSetMinMax(Widget widget, int min, int max) +{ + Pane pane = PaneInfo(widget); + + pane->min = min; + pane->max = max; + RefigureLocationsAndCommit(widget->core.parent); +} + +/* + * Function: + * XawPanedGetMinMax + * + * Parameters: + * widget - widget that is a child of the Paned widget + * min - current min and max size for the pane (return) + * max - "" + * + * Description: + * Gets the min and max size for a pane. + */ +void +XawPanedGetMinMax(Widget widget, int *min, int *max) +{ + Pane pane = PaneInfo(widget); + + *min = pane->min; + *max = pane->max; +} + +/* + * Function: + * XawPanedSetRefigureMode + * + * Parameters: + * w - paned widget + * mode - if False then inhibit refigure + * + * Description: + * Allows a flag to be set the will inhibit + * the paned widgets relayout routine. + */ +void +XawPanedSetRefigureMode(Widget w, +#if NeedWidePrototypes + int mode +#else + Boolean mode +#endif +) +{ + ((PanedWidget)w)->paned.refiguremode = mode; + RefigureLocationsAndCommit(w); +} + +/* + * Function: + * XawPanedGetNumSub + * + * Parameters: + * w - paned widget + * + * Description: + * Returns the number of panes in the paned widget. + * Returns: + * the number of panes in the paned widget + */ +int +XawPanedGetNumSub(Widget w) +{ + return (((PanedWidget)w)->paned.num_panes); +} + +/* + * Function: + * XawPanedAllowResize + * + * Parameters: + * widget - child of the paned widget + * + * Description: + * Allows a flag to be set that determines if the paned + * widget will allow geometry requests from this child. + */ +void +XawPanedAllowResize(Widget widget, +#if NeedWidePrototypes + int allow_resize +#else + Boolean allow_resize +#endif +) +{ + PaneInfo(widget)->allow_resize = allow_resize; +} diff --git a/src/Panner.c b/src/Panner.c new file mode 100644 index 0000000..aa90233 --- /dev/null +++ b/src/Panner.c @@ -0,0 +1,1079 @@ +/* + * +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#if defined(ISC) && __STDC__ && !defined(ISC30) +extern double atof(char *); +#else +#include /* for atof() */ +#endif + +/* + * Class Methods + */ +static void XawPannerDestroy(Widget); +static void XawPannerInitialize(Widget, Widget, ArgList, Cardinal*); +static XtGeometryResult XawPannerQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawPannerRealize(Widget, XtValueMask*, XSetWindowAttributes*); +static void XawPannerRedisplay(Widget, XEvent*, Region); +static void XawPannerResize(Widget); +static Boolean XawPannerSetValues(Widget, Widget, Widget, ArgList, Cardinal*); +static void XawPannerSetValuesAlmost(Widget, Widget, XtWidgetGeometry*, + XtWidgetGeometry*); + +/* + * Prototypes + */ +static void check_knob(PannerWidget, Bool); +static void get_default_size(PannerWidget, Dimension*, Dimension*); +static Bool get_event_xy(PannerWidget, XEvent*, int*, int*); +static void move_shadow(PannerWidget); +static int parse_page_string(char*, int, int, Bool*); +static void rescale(PannerWidget); +static void reset_shadow_gc(PannerWidget); +static void reset_slider_gc(PannerWidget); +static void reset_xor_gc(PannerWidget); +static void scale_knob(PannerWidget, Bool, Bool); + +/* + * Actions + */ +static void ActionAbort(Widget, XEvent*, String*, Cardinal*); +static void ActionMove(Widget, XEvent*, String*, Cardinal*); +static void ActionNotify(Widget, XEvent*, String*, Cardinal*); +static void ActionPage(Widget, XEvent*, String*, Cardinal*); +static void ActionSet(Widget, XEvent*, String*, Cardinal*); +static void ActionStart(Widget, XEvent*, String*, Cardinal*); +static void ActionStop(Widget, XEvent*, String*, Cardinal*); + +/* + * From Xmu/Distinct.c + */ +Bool XmuDistinguishablePixels(Display*, Colormap, unsigned long*, int); + +/* + * Initialization + */ +static char defaultTranslations[] = +":" "start()\n" +":" "move()\n" +":" "notify() stop()\n" +":" "abort()\n" +":KP_Enter:" "set(rubberband,toggle)\n" +"space:" "page(+1p,+1p)\n" +"Delete:" "page(-1p,-1p)\n" +":KP_Delete:" "page(-1p,-1p)\n" +"BackSpace:" "page(-1p,-1p)\n" +"Left:" "page(-.5p,+0)\n" +":KP_Left:" "page(-.5p,+0)\n" +"Right:" "page(+.5p,+0)\n" +":KP_Right:" "page(+.5p,+0)\n" +"Up:" "page(+0,-.5p)\n" +":KP_Up:" "page(+0,-.5p)\n" +"Down:" "page(+0,+.5p)\n" +":KP_Down:" "page(+0,+.5p)\n" +"Home:" "page(0,0)\n" +":KP_Home:" "page(0,0)\n" +; + +static XtActionsRec actions[] = { + {"start", ActionStart}, /* start tmp graphics */ + {"stop", ActionStop}, /* stop tmp graphics */ + {"abort", ActionAbort}, /* punt */ + {"move", ActionMove}, /* move tmp graphics on Motion event */ + {"page", ActionPage}, /* page around usually from keyboard */ + {"notify", ActionNotify}, /* callback new position */ + {"set", ActionSet}, /* set various parameters */ +}; + +#define offset(field) XtOffsetOf(PannerRec, panner.field) +static XtResource resources[] = { + { + XtNallowOff, + XtCAllowOff, + XtRBoolean, + sizeof(Boolean), + offset(allow_off), + XtRImmediate, + (XtPointer)False + }, + { + XtNresize, + XtCResize, + XtRBoolean, + sizeof(Boolean), + offset(resize_to_pref), + XtRImmediate, + (XtPointer)True + }, + { + XtNreportCallback, + XtCReportCallback, + XtRCallback, + sizeof(XtPointer), + offset(report_callbacks), + XtRCallback, + NULL + }, + { + XtNdefaultScale, + XtCDefaultScale, + XtRDimension, + sizeof(Dimension), + offset(default_scale), + XtRImmediate, + (XtPointer)PANNER_DEFAULT_SCALE + }, + { + XtNrubberBand, + XtCRubberBand, + XtRBoolean, + sizeof(Boolean), + offset(rubber_band), + XtRImmediate, + (XtPointer)False + }, + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(foreground), + XtRString, + (XtPointer)XtDefaultBackground + }, + { + XtNinternalSpace, + XtCInternalSpace, + XtRDimension, + sizeof(Dimension), + offset(internal_border), + XtRImmediate, + (XtPointer)4 + }, + { + XtNlineWidth, + XtCLineWidth, + XtRDimension, + sizeof(Dimension), + offset(line_width), + XtRImmediate, + (XtPointer)0 + }, + { + XtNcanvasWidth, + XtCCanvasWidth, + XtRDimension, + sizeof(Dimension), + offset(canvas_width), + XtRImmediate, + (XtPointer)0 + }, + { + XtNcanvasHeight, + XtCCanvasHeight, + XtRDimension, + sizeof(Dimension), + offset(canvas_height), + XtRImmediate, + (XtPointer)0 + }, + { + XtNsliderX, + XtCSliderX, + XtRPosition, + sizeof(Position), + offset(slider_x), + XtRImmediate, + (XtPointer)0 + }, + { + XtNsliderY, + XtCSliderY, + XtRPosition, + sizeof(Position), + offset(slider_y), + XtRImmediate, + (XtPointer)0 + }, + { + XtNsliderWidth, + XtCSliderWidth, + XtRDimension, + sizeof(Dimension), + offset(slider_width), + XtRImmediate, + (XtPointer)0 + }, + { + XtNsliderHeight, + XtCSliderHeight, + XtRDimension, + sizeof(Dimension), + offset(slider_height), + XtRImmediate, + (XtPointer)0 + }, + { + XtNshadowColor, + XtCShadowColor, + XtRPixel, + sizeof(Pixel), + offset(shadow_color), + XtRString, + (XtPointer)XtDefaultForeground + }, + { + XtNshadowThickness, + XtCShadowThickness, + XtRDimension, + sizeof(Dimension), + offset(shadow_thickness), + XtRImmediate, + (XtPointer)2 + }, + { + XtNbackgroundStipple, + XtCBackgroundStipple, + XtRString, + sizeof(String), + offset(stipple_name), + XtRImmediate, + NULL + }, +}; +#undef offset + +#define Superclass (&simpleClassRec) +PannerClassRec pannerClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "Panner", /* class_name */ + sizeof(PannerRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawPannerInitialize, /* initialize */ + NULL, /* initialize_hook */ + XawPannerRealize, /* realize */ + actions, /* actions */ + XtNumber(actions), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawPannerDestroy, /* destroy */ + XawPannerResize, /* resize */ + XawPannerRedisplay, /* expose */ + XawPannerSetValues, /* set_values */ + NULL, /* set_values_hook */ + XawPannerSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + defaultTranslations, /* tm_table */ + XawPannerQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* panner */ + { + NULL, /* extension */ + } +}; + +WidgetClass pannerWidgetClass = (WidgetClass) &pannerClassRec; + + +/* + * Implementation + */ +static void +reset_shadow_gc(PannerWidget pw) +{ + XtGCMask valuemask = GCForeground; + XGCValues values; + unsigned long pixels[3]; + + if (pw->panner.shadow_gc) + XtReleaseGC((Widget)pw, pw->panner.shadow_gc); + + pixels[0] = pw->panner.foreground; + pixels[1] = pw->core.background_pixel; + pixels[2] = pw->panner.shadow_color; + + if (!pw->panner.stipple_name && + !XmuDistinguishablePixels(XtDisplay(pw), pw->core.colormap, + pixels, 3) && + XmuDistinguishablePixels(XtDisplay(pw), pw->core.colormap, + pixels, 2)) { + valuemask = GCTile | GCFillStyle; + values.fill_style = FillTiled; + values.tile = XmuCreateStippledPixmap(XtScreen((Widget)pw), + pw->panner.foreground, + pw->core.background_pixel, + pw->core.depth); + } + else { + if (!pw->panner.line_width && + !XmuDistinguishablePixels(XtDisplay(pw), pw->core.colormap, + pixels, 2)) + pw->panner.line_width = 1; + valuemask = GCForeground; + values.foreground = pw->panner.shadow_color; + } + if (pw->panner.line_width > 0) { + values.line_width = pw->panner.line_width; + valuemask |= GCLineWidth; + } + + pw->panner.shadow_gc = XtGetGC((Widget)pw, valuemask, &values); +} + +static void +reset_slider_gc(PannerWidget pw) +{ + XtGCMask valuemask = GCForeground; + XGCValues values; + + if (pw->panner.slider_gc) + XtReleaseGC((Widget)pw, pw->panner.slider_gc); + + values.foreground = pw->panner.foreground; + + pw->panner.slider_gc = XtGetGC((Widget)pw, valuemask, &values); +} + +static void +reset_xor_gc(PannerWidget pw) +{ + if (pw->panner.xor_gc) + XtReleaseGC((Widget)pw, pw->panner.xor_gc); + + if (pw->panner.rubber_band) { + XtGCMask valuemask = (GCForeground | GCFunction); + XGCValues values; + Pixel tmp; + + tmp = (pw->panner.foreground == pw->core.background_pixel ? + pw->panner.shadow_color : pw->panner.foreground); + values.foreground = tmp ^ pw->core.background_pixel; + values.function = GXxor; + if (pw->panner.line_width > 0) { + valuemask |= GCLineWidth; + values.line_width = pw->panner.line_width; + } + pw->panner.xor_gc = XtGetGC((Widget)pw, valuemask, &values); + } + else + pw->panner.xor_gc = NULL; +} + +static void +check_knob(PannerWidget pw, Bool knob) +{ + Position pad = pw->panner.internal_border << 1; + Position maxx = (Position)XtWidth(pw) - pad - + (Position)pw->panner.knob_width; + Position maxy = (Position)XtHeight(pw) - pad - + (Position)pw->panner.knob_height; + Position *x = knob ? &pw->panner.knob_x : &pw->panner.tmp.x; + Position *y = knob ? &pw->panner.knob_y : &pw->panner.tmp.y; + + /* + * note that positions are already normalized (i.e. internal_border + * has been subtracted out) + */ + if (*x < 0) + *x = 0; + if (*x > maxx) + *x = maxx; + + if (*y < 0) + *y = 0; + if (*y > maxy) + *y = maxy; + + if (knob) { + pw->panner.slider_x = (Position)((double)pw->panner.knob_x + / pw->panner.haspect + 0.5); + pw->panner.slider_y = (Position)((double)pw->panner.knob_y + / pw->panner.vaspect + 0.5); + pw->panner.last_x = pw->panner.last_y = PANNER_OUTOFRANGE; + } +} + +static void +move_shadow(PannerWidget pw) +{ + if (pw->panner.shadow_thickness > 0) { + int lw = pw->panner.shadow_thickness + (pw->panner.line_width << 1); + int pad = pw->panner.internal_border; + + if (pw->panner.knob_height > lw && pw->panner.knob_width > lw) { + XRectangle *r = pw->panner.shadow_rects; + + r->x = pw->panner.knob_x + pad + pw->panner.knob_width; + r->y = pw->panner.knob_y + pad + lw; + r->width = pw->panner.shadow_thickness; + r->height = pw->panner.knob_height - lw; + r++; + r->x = pw->panner.knob_x + pad + lw; + r->y = pw->panner.knob_y + pad + pw->panner.knob_height; + r->width = pw->panner.knob_width - lw + pw->panner.shadow_thickness; + r->height = pw->panner.shadow_thickness; + pw->panner.shadow_valid = True; + return; + } + } + pw->panner.shadow_valid = False; +} + +static void +scale_knob(PannerWidget pw, Bool location, Bool size) +{ + if (location) { + pw->panner.knob_x = (Position)PANNER_HSCALE(pw, pw->panner.slider_x); + pw->panner.knob_y = (Position)PANNER_VSCALE(pw, pw->panner.slider_y); + } + if (size) { + Dimension width, height; + + if (pw->panner.slider_width < 1) + pw->panner.slider_width = pw->panner.canvas_width; + if (pw->panner.slider_height < 1) + pw->panner.slider_height = pw->panner.canvas_height; + width = Min(pw->panner.slider_width, pw->panner.canvas_width); + height = Min(pw->panner.slider_height, pw->panner.canvas_height); + + pw->panner.knob_width = (Dimension)PANNER_HSCALE(pw, width); + pw->panner.knob_height = (Dimension)PANNER_VSCALE(pw, height); + } + if (!pw->panner.allow_off) + check_knob(pw, True); + move_shadow(pw); +} + +static void +rescale(PannerWidget pw) +{ + int hpad = pw->panner.internal_border << 1; + int vpad = hpad; + + if (pw->panner.canvas_width < 1) + pw->panner.canvas_width = XtWidth(pw); + if (pw->panner.canvas_height < 1) + pw->panner.canvas_height = XtHeight(pw); + + if (XtWidth(pw) <= hpad) + hpad = 0; + if (XtHeight(pw) <= vpad) + vpad = 0; + + pw->panner.haspect = ((double)XtWidth(pw) - hpad + .5) + / (double)pw->panner.canvas_width; + pw->panner.vaspect = ((double)XtHeight(pw) - vpad + .5) + / (double)pw->panner.canvas_height; + scale_knob(pw, True, True); +} + +static void +get_default_size(PannerWidget pw, Dimension *wp, Dimension *hp) +{ + Dimension pad = pw->panner.internal_border << 1; + + *wp = PANNER_DSCALE(pw, pw->panner.canvas_width) + pad; + *hp = PANNER_DSCALE(pw, pw->panner.canvas_height) + pad; +} + +static Bool +get_event_xy(PannerWidget pw, XEvent *event, int *x, int *y) +{ + int pad = pw->panner.internal_border; + + switch (event->type) { + case ButtonPress: + case ButtonRelease: + *x = event->xbutton.x - pad; + *y = event->xbutton.y - pad; + return (True); + case KeyPress: + case KeyRelease: + *x = event->xkey.x - pad; + *y = event->xkey.y - pad; + return (True); + case EnterNotify: + case LeaveNotify: + *x = event->xcrossing.x - pad; + *y = event->xcrossing.y - pad; + return (True); + case MotionNotify: + *x = event->xmotion.x - pad; + *y = event->xmotion.y - pad; + return (True); + } + + return (False); +} + +static int +parse_page_string(char *s, int pagesize, int canvassize, Bool *relative) +{ + char *cp; + double val = 1.0; + Bool rel = False; + + /* + * syntax: spaces [+-] number spaces [pc\0] spaces + */ + for (; isascii(*s) && isspace(*s); s++) /* skip white space */ + ; + + if (*s == '+' || *s == '-') { /* deal with signs */ + rel = True; + if (*s == '-') + val = -1.0; + s++; + } + if (!*s) { /* if null then return nothing */ + *relative = True; + return (0); + } + + /* skip over numbers */ + for (cp = s; isascii(*s) && (isdigit(*s) || *s == '.'); s++) + ; + val *= atof(cp); + + /* skip blanks */ + for (; isascii(*s) && isspace(*s); s++) + ; + + if (*s) { /* if units */ + switch (s[0]) { + case 'p': + case 'P': + val *= (double)pagesize; + break; + case 'c': + case 'C': + val *= (double)canvassize; + break; + } + } + *relative = rel; + + return ((int)val); +} + +#define DRAW_TMP(pw) \ +{ \ + XDrawRectangle(XtDisplay(pw), XtWindow(pw), \ + pw->panner.xor_gc, \ + pw->panner.tmp.x + pw->panner.internal_border, \ + pw->panner.tmp.y + pw->panner.internal_border, \ + pw->panner.knob_width - 1, \ + pw->panner.knob_height - 1); \ + pw->panner.tmp.showing = !pw->panner.tmp.showing; \ +} + +#define UNDRAW_TMP(pw) \ +{ \ + if (pw->panner.tmp.showing) \ + DRAW_TMP(pw); \ +} + +#define BACKGROUND_STIPPLE(pw) \ +XmuLocatePixmapFile(pw->core.screen, pw->panner.stipple_name, \ + pw->panner.shadow_color, pw->core.background_pixel, \ + pw->core.depth, NULL, 0, NULL, NULL, NULL, NULL) + +#define PIXMAP_OKAY(pm) ((pm) != None && (pm) != XtUnspecifiedPixmap) + +/*ARGSUSED*/ +static void +XawPannerInitialize(Widget greq, Widget gnew, ArgList args, Cardinal *num_args) +{ + PannerWidget req = (PannerWidget)greq, cnew = (PannerWidget)gnew; + Dimension defwidth, defheight; + + if (req->panner.canvas_width < 1) + cnew->panner.canvas_width = 1; + if (req->panner.canvas_height < 1) + cnew->panner.canvas_height = 1; + if (req->panner.default_scale < 1) + cnew->panner.default_scale = PANNER_DEFAULT_SCALE; + + get_default_size(req, &defwidth, &defheight); + if (XtWidth(req) < 1) + XtWidth(cnew) = defwidth; + if (XtHeight(req) < 1) + XtHeight(cnew) = defheight; + + cnew->panner.shadow_gc = NULL; + reset_shadow_gc(cnew); /* shadowColor */ + cnew->panner.slider_gc = NULL; + reset_slider_gc(cnew); /* foreground */ + cnew->panner.xor_gc = NULL; + reset_xor_gc(cnew); /* foreground ^ background */ + + rescale(cnew); /* does a position check */ + cnew->panner.shadow_valid = False; + cnew->panner.tmp.doing = False; + cnew->panner.tmp.showing = False; + } + +static void +XawPannerRealize(Widget gw, XtValueMask *valuemaskp, + XSetWindowAttributes *attr) +{ + PannerWidget pw = (PannerWidget)gw; + Pixmap pm = XtUnspecifiedPixmap; + Bool gotpm = False; + + if (pw->core.background_pixmap == XtUnspecifiedPixmap) { + if (pw->panner.stipple_name) + pm = BACKGROUND_STIPPLE(pw); + + if (PIXMAP_OKAY(pm)) { + attr->background_pixmap = pm; + *valuemaskp |= CWBackPixmap; + *valuemaskp &= ~CWBackPixel; + gotpm = True; + } + } + (*pannerWidgetClass->core_class.superclass->core_class.realize) + (gw, valuemaskp, attr); + + if (gotpm) + XFreePixmap(XtDisplay(gw), pm); +} + +static void +XawPannerDestroy(Widget gw) +{ + PannerWidget pw = (PannerWidget)gw; + + XtReleaseGC(gw, pw->panner.shadow_gc); + XtReleaseGC(gw, pw->panner.slider_gc); + XtReleaseGC(gw, pw->panner.xor_gc); +} + +static void +XawPannerResize(Widget gw) +{ + rescale((PannerWidget)gw); +} + +static void +XawPannerRedisplay(Widget gw, XEvent *event, Region region) +{ + PannerWidget pw = (PannerWidget)gw; + Display *dpy = XtDisplay(gw); + Window w = XtWindow(gw); + int pad = pw->panner.internal_border; + Dimension lw = pw->panner.line_width; + Dimension extra = pw->panner.shadow_thickness + (lw << 1); + int kx = pw->panner.knob_x + pad, ky = pw->panner.knob_y + pad; + + if (Superclass->core_class.expose) + (Superclass->core_class.expose)(gw, event, region); + + pw->panner.tmp.showing = False; + XClearArea(XtDisplay(pw), XtWindow(pw), + (int)pw->panner.last_x - ((int)lw) + pad, + (int)pw->panner.last_y - ((int)lw) + pad, + pw->panner.knob_width + extra, + pw->panner.knob_height + extra, + False); + pw->panner.last_x = pw->panner.knob_x; + pw->panner.last_y = pw->panner.knob_y; + + XFillRectangle(dpy, w, pw->panner.slider_gc, kx, ky, + pw->panner.knob_width - 1, pw->panner.knob_height - 1); + + if (lw) + XDrawRectangle(dpy, w, pw->panner.shadow_gc, kx, ky, + pw->panner.knob_width - 1, pw->panner.knob_height - 1); + + if (pw->panner.shadow_valid) + XFillRectangles(dpy, w, pw->panner.shadow_gc, pw->panner.shadow_rects, 2); + + if (pw->panner.tmp.doing && pw->panner.rubber_band) + DRAW_TMP(pw); +} + +/*ARGSUSED*/ +static Boolean +XawPannerSetValues(Widget gcur, Widget greq, Widget gnew, + ArgList args, Cardinal *num_args) +{ + PannerWidget cur = (PannerWidget)gcur; + PannerWidget cnew = (PannerWidget)gnew; + Bool redisplay = False; + + if (cur->panner.foreground != cnew->panner.foreground) { + reset_slider_gc(cnew); + if (cur->panner.foreground != cur->core.background_pixel) + reset_xor_gc(cnew); + redisplay = True; + } + else if (cur->panner.line_width != cnew->panner.line_width || + cur->core.background_pixel != cnew->core.background_pixel) { + reset_xor_gc(cnew); + redisplay = True; + } + if (cur->panner.shadow_color != cnew->panner.shadow_color) { + reset_shadow_gc(cnew); + if (cur->panner.foreground == cur->core.background_pixel) + reset_xor_gc(cnew); + redisplay = True; + } + if (cur->panner.shadow_thickness != cnew->panner.shadow_thickness) { + move_shadow(cnew); + redisplay = True; + } + if (cur->panner.rubber_band != cnew->panner.rubber_band) { + reset_xor_gc(cnew); + if (cnew->panner.tmp.doing) + redisplay = True; + } + + if ((cur->panner.stipple_name != cnew->panner.stipple_name + || cur->panner.shadow_color != cnew->panner.shadow_color + || cur->core.background_pixel != cnew->core.background_pixel) + && XtIsRealized(gnew)) { + Pixmap pm = cnew->panner.stipple_name ? + BACKGROUND_STIPPLE(cnew) : XtUnspecifiedPixmap; + + if (PIXMAP_OKAY(pm)) { + XSetWindowBackgroundPixmap(XtDisplay(cnew), XtWindow(cnew), pm); + XFreePixmap(XtDisplay(cnew), pm); + } + else + XSetWindowBackground(XtDisplay(cnew), XtWindow(cnew), + cnew->core.background_pixel); + + redisplay = True; + } + + if (cnew->panner.resize_to_pref && + (cur->panner.canvas_width != cnew->panner.canvas_width + || cur->panner.canvas_height != cnew->panner.canvas_height + || cur->panner.resize_to_pref != cnew->panner.resize_to_pref)) { + get_default_size(cnew, &cnew->core.width, &cnew->core.height); + redisplay = True; + } + else if (cur->panner.canvas_width != cnew->panner.canvas_width + || cur->panner.canvas_height != cnew->panner.canvas_height + || cur->panner.internal_border != cnew->panner.internal_border) { + rescale(cnew); /* does a scale_knob as well */ + redisplay = True; + } + else { + Bool loc = cur->panner.slider_x != cnew->panner.slider_x || + cur->panner.slider_y != cnew->panner.slider_y; + Bool siz = cur->panner.slider_width != cnew->panner.slider_width || + cur->panner.slider_height != cnew->panner.slider_height; + if (loc || siz || (cur->panner.allow_off != cnew->panner.allow_off + && cnew->panner.allow_off)) { + scale_knob(cnew, loc, siz); + redisplay = True; + } + } + + return (redisplay); +} + +static void +XawPannerSetValuesAlmost(Widget gold, Widget gnew, XtWidgetGeometry *req, + XtWidgetGeometry *reply) +{ + if (reply->request_mode == 0) /* got turned down, so cope */ + XawPannerResize(gnew); + + (*pannerWidgetClass->core_class.superclass->core_class.set_values_almost) + (gold, gnew, req, reply); +} + +static XtGeometryResult +XawPannerQueryGeometry(Widget gw, XtWidgetGeometry *intended, + XtWidgetGeometry *pref) +{ + PannerWidget pw = (PannerWidget)gw; + + pref->request_mode = (CWWidth | CWHeight); + get_default_size(pw, &pref->width, &pref->height); + + if (((intended->request_mode & (CWWidth | CWHeight)) == (CWWidth | CWHeight)) + && intended->width == pref->width && intended->height == pref->height) + return (XtGeometryYes); + else if (pref->width == XtWidth(pw) && pref->height == XtHeight(pw)) + return (XtGeometryNo); + + return (XtGeometryAlmost); +} + + +/*ARGSUSED*/ +static void +ActionStart(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + PannerWidget pw = (PannerWidget)gw; + int x, y; + + if (!get_event_xy(pw, event, &x, &y)) { + XBell(XtDisplay(gw), 0); + return; + } + + pw->panner.tmp.doing = True; + pw->panner.tmp.startx = pw->panner.knob_x; + pw->panner.tmp.starty = pw->panner.knob_y; + pw->panner.tmp.dx = x - pw->panner.knob_x; + pw->panner.tmp.dy = y - pw->panner.knob_y; + pw->panner.tmp.x = pw->panner.knob_x; + pw->panner.tmp.y = pw->panner.knob_y; + if (pw->panner.rubber_band) + DRAW_TMP(pw); +} + +/*ARGSUSED*/ +static void +ActionStop(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + PannerWidget pw = (PannerWidget)gw; + int x, y; + + if (get_event_xy(pw, event, &x, &y)) { + pw->panner.tmp.x = x - pw->panner.tmp.dx; + pw->panner.tmp.y = y - pw->panner.tmp.dy; + if (!pw->panner.allow_off) + check_knob(pw, False); + } + if (pw->panner.rubber_band) + DRAW_TMP(pw); + pw->panner.tmp.doing = False; +} + +static void +ActionAbort(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + PannerWidget pw = (PannerWidget)gw; + + if (!pw->panner.tmp.doing) + return; + + if (pw->panner.rubber_band) + UNDRAW_TMP(pw); + + if (!pw->panner.rubber_band) { /* restore old position */ + pw->panner.tmp.x = pw->panner.tmp.startx; + pw->panner.tmp.y = pw->panner.tmp.starty; + ActionNotify(gw, event, params, num_params); + } + pw->panner.tmp.doing = False; +} + +static void +ActionMove(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + PannerWidget pw = (PannerWidget)gw; + int x, y; + + if (!pw->panner.tmp.doing) + return; + + if (!get_event_xy(pw, event, &x, &y)) { + XBell(XtDisplay(gw), 0); /* should do error message */ + return; + } + + if (pw->panner.rubber_band) + UNDRAW_TMP(pw); + pw->panner.tmp.x = x - pw->panner.tmp.dx; + pw->panner.tmp.y = y - pw->panner.tmp.dy; + + if (!pw->panner.rubber_band) + ActionNotify(gw, event, params, num_params); + else { + if (!pw->panner.allow_off) + check_knob(pw, False); + DRAW_TMP(pw); + } +} + + +static void +ActionPage(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + PannerWidget pw = (PannerWidget)gw; + Cardinal zero = 0; + Bool isin = pw->panner.tmp.doing; + int x, y; + Bool relx, rely; + int pad = pw->panner.internal_border << 1; + + if (*num_params != 2) { + XBell(XtDisplay(gw), 0); + return; + } + + x = parse_page_string(params[0], pw->panner.knob_width, + (int)XtWidth(pw) - pad, &relx); + y = parse_page_string(params[1], pw->panner.knob_height, + (int)XtHeight(pw) - pad, &rely); + + if (relx) + x += pw->panner.knob_x; + if (rely) + y += pw->panner.knob_y; + + if (isin) { /* if in, then use move */ + XEvent ev; + + ev.xbutton.type = ButtonPress; + ev.xbutton.x = x; + ev.xbutton.y = y; + ActionMove(gw, &ev, NULL, &zero); + } + else { + pw->panner.tmp.doing = True; + pw->panner.tmp.x = x; + pw->panner.tmp.y = y; + ActionNotify(gw, event, NULL, &zero); + pw->panner.tmp.doing = False; + } +} + +/*ARGSUSED*/ +static void +ActionNotify(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + PannerWidget pw = (PannerWidget)gw; + + if (!pw->panner.tmp.doing) + return; + + if (!pw->panner.allow_off) + check_knob(pw, False); + pw->panner.knob_x = pw->panner.tmp.x; + pw->panner.knob_y = pw->panner.tmp.y; + move_shadow(pw); + + pw->panner.slider_x = (Position)((double)pw->panner.knob_x + / pw->panner.haspect + 0.5); + pw->panner.slider_y = (Position)((double) pw->panner.knob_y + / pw->panner.vaspect + 0.5); + if (!pw->panner.allow_off) { + Position tmp; + + if (pw->panner.slider_x + > (tmp = (Position)pw->panner.canvas_width - + (Position)pw->panner.slider_width)) + pw->panner.slider_x = tmp; + if (pw->panner.slider_x < 0) + pw->panner.slider_x = 0; + if (pw->panner.slider_y + > (tmp = (Position)pw->panner.canvas_height - + (Position)pw->panner.slider_height)) + pw->panner.slider_y = tmp; + if (pw->panner.slider_y < 0) + pw->panner.slider_y = 0; + } + + if (pw->panner.last_x != pw->panner.knob_x || + pw->panner.last_y != pw->panner.knob_y) { + XawPannerReport rep; + + XawPannerRedisplay(gw, NULL, NULL); + rep.changed = XawPRSliderX | XawPRSliderY; + rep.slider_x = pw->panner.slider_x; + rep.slider_y = pw->panner.slider_y; + rep.slider_width = pw->panner.slider_width; + rep.slider_height = pw->panner.slider_height; + rep.canvas_width = pw->panner.canvas_width; + rep.canvas_height = pw->panner.canvas_height; + XtCallCallbackList(gw, pw->panner.report_callbacks, (XtPointer)&rep); + } +} + +/*ARGSUSED*/ +static void +ActionSet(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + PannerWidget pw = (PannerWidget)gw; + Bool rb; + + if (*num_params < 2 || + XmuCompareISOLatin1(params[0], "rubberband") != 0) { + XBell(XtDisplay(gw), 0); + return; + } + + if (XmuCompareISOLatin1(params[1], "on") == 0) + rb = True; + else if (XmuCompareISOLatin1(params[1], "off") == 0) + rb = False; + else if (XmuCompareISOLatin1(params[1], "toggle") == 0) + rb = !pw->panner.rubber_band; + else { + XBell(XtDisplay(gw), 0); + return; + } + + if (rb != pw->panner.rubber_band) { + Arg args[1]; + + XtSetArg(args[0], XtNrubberBand, rb); + XtSetValues(gw, args, 1); + } +} diff --git a/src/Pixmap.c b/src/Pixmap.c new file mode 100644 index 0000000..6e3388c --- /dev/null +++ b/src/Pixmap.c @@ -0,0 +1,991 @@ +/* + * Copyright (c) 1998 by The XFree86 Project, Inc. + * + * 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 XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#ifndef OLDXAW +#include +#endif +#include "Private.h" + +#ifdef __UNIXOS2__ +static char dummy; +#endif + +#ifndef OLDXAW + +/* + * Types + */ +typedef struct _XawCache { + long value; + XtPointer *elems; + unsigned int num_elems; +} XawCache; + +typedef struct _XawPixmapLoaderInfo { + XawPixmapLoader loader; + String type; + String ext; +} XawPixmapLoaderInfo; + +/* + * Private Methods + */ +static Bool BitmapLoader(XawParams*, Screen*, Colormap, int, + Pixmap*, Pixmap*, Dimension*, Dimension*); +static Bool GradientLoader(XawParams*, Screen*, Colormap, int, + Pixmap*, Pixmap*, Dimension*, Dimension*); +static Bool XPixmapLoader(XawParams*, Screen*, Colormap, int, + Pixmap*, Pixmap*, Dimension*, Dimension*); +static XawPixmap *_XawFindPixmap(String, Screen*, Colormap, int); +static void _XawCachePixmap(XawPixmap*, Screen*, Colormap, int); +static int _XawFindPixmapLoaderIndex(String, String); +static int qcmp_long(register _Xconst void*, register _Xconst void *); +static int bcmp_long(register _Xconst void*, register _Xconst void *); +static int qcmp_string(register _Xconst void*, register _Xconst void *); +static int bcmp_string(register _Xconst void*, register _Xconst void *); +static void GetResourcePixmapPath(Display*); + +/* + * Initialization + */ +static XawCache xaw_pixmaps; +static XawCache x_pixmaps; /* for fast reverse search */ +static XawPixmapLoaderInfo **loader_info; +static Cardinal num_loader_info; + +/* + * Implementation + */ +Bool +XawPixmapsInitialize(void) +{ + static Boolean first_time = True; + + if (!first_time) + return (False); + + (void)XawAddPixmapLoader(NULL, NULL, BitmapLoader); + (void)XawAddPixmapLoader("bitmap", NULL, BitmapLoader); + (void)XawAddPixmapLoader("gradient", NULL, GradientLoader); + (void)XawAddPixmapLoader("xpm", "xpm", XPixmapLoader); + + return (True); +} + +XawParams * +XawParseParamsString(String name) +{ + XawParams *xaw_params; + char *tok, *str, *type = NULL, *ext = NULL, *params = NULL; + + if (!name) + return (NULL); + + xaw_params = (XawParams *)XtMalloc(sizeof(XawParams)); + + str = XtNewString(name); + + /* Find type */ + tok = str; + while (tok = strchr(tok, ':'), tok) + { + if (tok == str || tok[-1] != '\\') + break; + memmove(&tok[-1], tok, strlen(tok) + 1); + } + if (tok) + { + *tok = '\0'; + if (strchr(str, '?')) + { + *tok = ':'; + } + else + { + ++tok; + type = XtNewString(str); + memmove(str, tok, strlen(tok) + 1); + } + } + + /* Find params */ + tok = str; + while (tok = strchr(tok, '?'), tok) + { + if (tok == str || tok[-1] != '\\') + params = tok; + if (tok != str && tok[-1] == '\\') + memmove(&tok[-1], tok, strlen(tok) + 1); + else + break; + } + if (params) + { + *params = '\0'; + ++params; + } + + /* Find ext */ + tok = str; + while (tok = strchr(tok, '.'), tok) + { + if (tok == str || tok[-1] != '\\') + ext = tok; + if (tok != str && tok[-1] == '\\') + memmove(&tok[-1], tok, strlen(tok) + 1); + else + break; + } + if (ext) + { + ++ext; + if (strchr(ext, '/')) + ext = NULL; + } + + xaw_params->name = XtNewString(str); + xaw_params->type = type; + xaw_params->ext = ext ? XtNewString(ext) : ext; + xaw_params->args = NULL; + xaw_params->num_args = 0; + + /* Parse params */ + if (params) + { + char *arg, *val; + XawArgVal *xaw_arg; + + for (tok = strtok(params, "&"); tok; tok = strtok(NULL, "&")) + { + val = strchr(tok, '='); + if (val) + { + *val = '\0'; + ++val; + if (*val != '\0') + val = XtNewString(val); + else + val = NULL; + } + arg = XtNewString(tok); + xaw_arg = (XawArgVal *)XtMalloc(sizeof(XawArgVal)); + xaw_arg->name = arg; + xaw_arg->value = val; + if (!xaw_params->num_args) + { + xaw_params->num_args = 1; + xaw_params->args = (XawArgVal **) + XtMalloc(sizeof(XawArgVal*)); + } + else + { + ++xaw_params->num_args; + xaw_params->args = (XawArgVal **) + XtRealloc((char *)xaw_params->args, + sizeof(XawArgVal*) * xaw_params->num_args); + } + xaw_params->args[xaw_params->num_args - 1] = xaw_arg; + } + } + + if (xaw_params->num_args > 1) + qsort(xaw_params->args, xaw_params->num_args, sizeof(XtPointer), + qcmp_string); + + XtFree(str); + + return (xaw_params); +} + +void +XawFreeParamsStruct(XawParams *params) +{ + unsigned int i; + + if (!params) + return; + + for (i = 0; i < params->num_args; i++) + { + XtFree(params->args[i]->name); + if (params->args[i]->value) + XtFree(params->args[i]->value); + XtFree((char *)params->args[i]); + } + + if (params->args) + XtFree((char *)params->args); + XtFree((char *)params); +} + +XawArgVal * +XawFindArgVal(XawParams *params, String name) +{ + XawArgVal **arg_val; + + if (!params->args) + return (NULL); + + arg_val = (XawArgVal **)bsearch((void *)name, params->args, + params->num_args, sizeof(XtPointer*), + bcmp_string); + if (!arg_val) + return (NULL); + + return (*arg_val); +} + +XawPixmap * +XawLoadPixmap(String name, Screen *screen, Colormap colormap, int depth) +{ + int idx; + Bool success; + XawPixmap *xaw_pixmap; + Pixmap pixmap, mask; + Dimension width, height; + XawParams *xaw_params; + + if (!name) + return (NULL); + + xaw_pixmap = _XawFindPixmap(name, screen, colormap, depth); + + if (xaw_pixmap) + return (xaw_pixmap); + + if ((xaw_params = XawParseParamsString(name)) == NULL) + return (NULL); + + idx = _XawFindPixmapLoaderIndex(xaw_params->type, xaw_params->ext); + if (idx < 0) + return (NULL); + +#ifdef DIAGNOSTIC + fprintf(stderr, "(*) Loading pixmap \"%s\": ", name); +#endif + + success = loader_info[idx]->loader(xaw_params, screen, colormap, depth, + &pixmap, &mask, &width, &height); + if (success) + { + xaw_pixmap = (XawPixmap *)XtMalloc(sizeof(XawPixmap)); + xaw_pixmap->name = XtNewString(name); + xaw_pixmap->pixmap = pixmap; + xaw_pixmap->mask = mask; + xaw_pixmap->width = width; + xaw_pixmap->height = height; + _XawCachePixmap(xaw_pixmap, screen, colormap, depth); + } + + XawFreeParamsStruct(xaw_params); + +#ifdef DIAGNOSTIC + fprintf(stderr, "%s", success ? "success\n" : "failed\n"); +#endif + + return (success ? xaw_pixmap : NULL); +} + +Bool +XawAddPixmapLoader(String type, String ext, XawPixmapLoader loader) +{ + XawPixmapLoaderInfo *info; + int i; + + if (!loader) + return (False); + + i = _XawFindPixmapLoaderIndex(type, ext); + + if (i >= 0) + { + loader_info[i]->loader = loader; + if (loader_info[i]->type) + XtFree(loader_info[i]->type); + if (loader_info[i]->ext) + XtFree(loader_info[i]->ext); + loader_info[i]->type = type ? XtNewString(type) : NULL; + loader_info[i]->ext = ext ? XtNewString(ext) : NULL; + return (True); + } + + if ((info = (XawPixmapLoaderInfo *)XtMalloc(sizeof(XawPixmapLoaderInfo))) + == NULL) + return (False); + + info->loader = loader; + info->type = type ? XtNewString(type) : NULL; + info->ext = ext ? XtNewString(ext) : NULL; + + if (!loader_info) + { + num_loader_info = 1; + loader_info = (XawPixmapLoaderInfo**) + XtMalloc(sizeof(XawPixmapLoaderInfo*)); + } + else + { + ++num_loader_info; + loader_info = (XawPixmapLoaderInfo**) + XtRealloc((char *)loader_info, + sizeof(XawPixmapLoaderInfo) * num_loader_info); + } + loader_info[num_loader_info - 1] = info; + + return (True); +} + +static int +_XawFindPixmapLoaderIndex(String type, String ext) +{ + Cardinal i; + + if (!loader_info) + return (-1); + + for (i = 0; i < num_loader_info; i++) + if ((type && loader_info[i]->type && strcmp(type, loader_info[i]->type) == 0) + || (ext && loader_info[i]->ext && strcmp(ext, loader_info[i]->ext) == 0)) + return ((int)i); + + if (!type) + return (0); /* try a bitmap */ + + return (-1); +} + +static int +qcmp_x_cache(register _Xconst void *left, register _Xconst void *right) +{ + return ((int)((*(XawPixmap **)left)->pixmap) - + (int)((*(XawPixmap **)right)->pixmap)); +} + +static int +bcmp_x_cache(register _Xconst void *pixmap, register _Xconst void *xaw) +{ + return (int)((long)pixmap - (long)((*(XawPixmap **)xaw)->pixmap)); +} + +static int +qcmp_long(register _Xconst void *left, register _Xconst void *right) +{ + return ((long)((*(XawCache **)left)->value) - + (long)((*(XawCache **)right)->value)); +} + +static int +qcmp_string(register _Xconst void *left, register _Xconst void *right) +{ + return (strcmp((String)((*(XawCache **)left)->value), + (String)((*(XawCache **)right)->value))); +} + +static int +bcmp_long(register _Xconst void *value, register _Xconst void *cache) +{ + return ((long)value - (long)((*(XawCache **)cache)->value)); +} + +static int +bcmp_string(register _Xconst void *string, + register _Xconst void *cache) +{ + return (strcmp((String)string, (String)((*(XawCache **)cache)->value))); +} + +#define FIND_ALL 0 +#define FIND_SCREEN 1 +#define FIND_COLORMAP 2 +#define FIND_DEPTH 3 +static XawCache * +_XawFindCache(XawCache *xaw, + Screen *screen, Colormap colormap, int depth, int flags) +{ + XawCache **cache; + + if (!xaw->num_elems) + return (NULL); + + /* Screen */ + cache = (XawCache **)bsearch(screen, xaw->elems, + xaw->num_elems, sizeof(XtPointer), + bcmp_long); + if (!cache || !(*cache)->num_elems) + return (NULL); + if (flags == FIND_SCREEN) + return (*cache); + + /* Colormap */ + cache = (XawCache **)bsearch((void *)colormap, (*cache)->elems, + (*cache)->num_elems, sizeof(XtPointer), + bcmp_long); + if (!cache || !(*cache)->num_elems) + return (NULL); + if (flags == FIND_COLORMAP) + return (*cache); + + /* Depth */ + cache = (XawCache **)bsearch((void *)(long)depth, (*cache)->elems, + (*cache)->num_elems, sizeof(XtPointer), + bcmp_long); + + if (!cache || !(*cache)->num_elems) + return (NULL); + return (*cache); +} + +static XawCache * +_XawGetCache(XawCache *xaw, Screen *screen, Colormap colormap, int depth) +{ + XawCache *s_cache, *c_cache, *d_cache, *cache, *pcache; + + cache = _XawFindCache(xaw, screen, colormap, depth, FIND_ALL); + + if (!cache) + { + s_cache = _XawFindCache(xaw, + screen, colormap, depth, FIND_SCREEN); + if (!s_cache) + { + pcache = (XawCache *)XtMalloc(sizeof(XawCache)); + if (!xaw->num_elems) + { + xaw->num_elems = 1; + xaw->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); + } + else + { + ++xaw->num_elems; + xaw->elems = (XtPointer*) + XtRealloc((char *)xaw->elems, + sizeof(XtPointer) * xaw->num_elems); + } + pcache->value = (long)screen; + pcache->elems = NULL; + pcache->num_elems = 0; + xaw->elems[xaw->num_elems - 1] = (XtPointer)pcache; + s_cache = (XawCache *)xaw->elems[xaw->num_elems - 1]; + if (xaw->num_elems > 1) + qsort(xaw->elems, xaw->num_elems, sizeof(XtPointer), qcmp_long); + } + + c_cache = _XawFindCache(xaw, + screen, colormap, depth, FIND_COLORMAP); + if (!c_cache) + { + pcache = (XawCache *)XtMalloc(sizeof(XawCache)); + if (!s_cache->num_elems) + { + s_cache->num_elems = 1; + s_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); + } + else + { + ++s_cache->num_elems; + s_cache->elems = (XtPointer*) + XtRealloc((char *)s_cache->elems, + sizeof(XtPointer) * s_cache->num_elems); + } + pcache->value = (long)colormap; + pcache->elems = NULL; + pcache->num_elems = 0; + s_cache->elems[s_cache->num_elems - 1] = (XtPointer)pcache; + c_cache = (XawCache *)s_cache->elems[s_cache->num_elems - 1]; + if (s_cache->num_elems > 1) + qsort(s_cache->elems, s_cache->num_elems, + sizeof(XtPointer), qcmp_long); + } + + d_cache = _XawFindCache(xaw, + screen, colormap, depth, FIND_DEPTH); + if (!d_cache) + { + pcache = (XawCache *)XtMalloc(sizeof(XawCache)); + if (!c_cache->num_elems) + { + c_cache->num_elems = 1; + c_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); + } + else + { + ++c_cache->num_elems; + c_cache->elems = (XtPointer*) + XtRealloc((char *)c_cache->elems, + sizeof(XtPointer) * c_cache->num_elems); + } + pcache->value = (long)depth; + pcache->elems = NULL; + pcache->num_elems = 0; + c_cache->elems[c_cache->num_elems - 1] = (XtPointer)pcache; + d_cache = (XawCache *)c_cache->elems[c_cache->num_elems - 1]; + if (c_cache->num_elems > 1) + qsort(c_cache->elems, c_cache->num_elems, + sizeof(XtPointer), qcmp_long); + } + + cache = d_cache; + } + + return (cache); +} + +static XawPixmap * +_XawFindPixmap(String name, Screen *screen, Colormap colormap, int depth) +{ + XawCache *cache; + XawPixmap **pixmap; + + cache = _XawFindCache(&xaw_pixmaps, screen, colormap, depth, FIND_ALL); + + if (!cache) + return (NULL); + + /* Name */ + pixmap = (XawPixmap **)bsearch((void *)name, cache->elems, + cache->num_elems, sizeof(XtPointer), + bcmp_string); + if (!pixmap) + return (NULL); + + return (*pixmap); +} + +XawPixmap * +XawPixmapFromXPixmap(Pixmap pixmap, + Screen *screen, Colormap colormap, int depth) +{ + XawCache *cache; + XawPixmap **x_pixmap; + + cache = _XawFindCache(&x_pixmaps, screen, colormap, depth, FIND_ALL); + + if (!cache) + return (NULL); + + /* Pixmap */ + x_pixmap = (XawPixmap **)bsearch((void *)pixmap, cache->elems, + cache->num_elems, sizeof(XtPointer), + bcmp_x_cache); + if (!x_pixmap) + return (NULL); + + return (*x_pixmap); +} + +static void +_XawCachePixmap(XawPixmap *pixmap, + Screen *screen, Colormap colormap, int depth) +{ + XawCache *xaw_cache, *x_cache; + + xaw_cache = _XawGetCache(&xaw_pixmaps, screen, colormap, depth); + x_cache = _XawGetCache(&x_pixmaps, screen, colormap, depth); + + if (!xaw_cache->num_elems) + { + xaw_cache->num_elems = 1; + xaw_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); + } + else + { + ++xaw_cache->num_elems; + xaw_cache->elems = (XtPointer*)XtRealloc((char *)xaw_cache->elems, + sizeof(XtPointer) * + xaw_cache->num_elems); + } + + xaw_cache->elems[xaw_cache->num_elems - 1] = (XtPointer)pixmap; + if (xaw_cache->num_elems > 1) + qsort(xaw_cache->elems, xaw_cache->num_elems, + sizeof(XtPointer), qcmp_string); + + + if (!x_cache->num_elems) + { + x_cache->num_elems = 1; + x_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); + } + else + { + ++x_cache->num_elems; + x_cache->elems = (XtPointer*)XtRealloc((char *)x_cache->elems, + sizeof(XtPointer) * + x_cache->num_elems); + } + + x_cache->elems[x_cache->num_elems - 1] = (XtPointer)pixmap; + if (x_cache->num_elems > 1) + qsort(x_cache->elems, x_cache->num_elems, sizeof(XtPointer), qcmp_x_cache); +} + +#ifndef PROJECT_ROOT +#define PROJECT_ROOT "/usr/X11R6" +#endif + +static char *pixmap_path = NULL; + +static void +GetResourcePixmapPath(Display *display) +{ + XrmName xrm_name[2]; + XrmClass xrm_class[2]; + XrmRepresentation rep_type; + XrmValue value; + static char *default_path = + "%H/%T/%N:%P/include/X11/%T/%N:/usr/X11R6/include/X11/%T/%N:/usr/include/X11/%T/%N:%N"; + + xrm_name[0] = XrmPermStringToQuark("pixmapFilePath"); + xrm_name[1] = NULLQUARK; + xrm_class[0] = XrmPermStringToQuark("PixmapFilePath"); + xrm_class[1] = NULLQUARK; + if (!XrmGetDatabase(display)) + (void) XGetDefault(display, "", ""); + if (XrmQGetResource(XrmGetDatabase(display), xrm_name, xrm_class, + &rep_type, &value) && + rep_type == XrmPermStringToQuark("String")) { + int length = 0; + char *tok, *buffer = XtNewString(value.addr); + + for (tok = strtok(buffer, ":"); tok; tok = strtok(NULL, ":")) { + int toklen = strlen(tok); + + if (toklen) { + pixmap_path = XtRealloc(pixmap_path, length + toklen + 5); + strcpy(pixmap_path + length, tok); + if (length) + pixmap_path[length++] = ':'; + sprintf(pixmap_path + length, "%s/%%N", tok); + length += strlen(tok) + 3; + } + } + pixmap_path = XtRealloc(pixmap_path, length + strlen(default_path) + 2); + if (length) + pixmap_path[length++] = ':'; + strcpy(pixmap_path + length, default_path); + } + else + pixmap_path = default_path; +} + +static Bool +BitmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth, + Pixmap *pixmap_return, Pixmap *mask_return, + Dimension *width_return, Dimension *height_return) +{ + Pixel fg, bg; + XColor color, exact; + Pixmap pixmap; + unsigned int width, height; + unsigned char *data = NULL; + int hotX, hotY; + XawArgVal *argval; + Bool retval = False; + static SubstitutionRec sub[] = { + {'H', NULL}, + {'N', NULL}, + {'T', "bitmaps"}, + {'P', PROJECT_ROOT}, + }; + char *filename; + + fg = BlackPixelOfScreen(screen); + bg = WhitePixelOfScreen(screen); + + if ((argval = XawFindArgVal(params, "foreground")) != NULL + && argval->value) + { + if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value, + &color, &exact)) + fg = color.pixel; + else + return (False); + } + if ((argval = XawFindArgVal(params, "background")) != NULL + && argval->value) + { + if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value, + &color, &exact)) + bg = color.pixel; + else + return (False); + } + + if (params->name[0] != '/' && params->name[0] != '.') + { + if (!sub[0].substitution) + sub[0].substitution = getenv("HOME"); + sub[1].substitution = params->name; + if (pixmap_path == NULL) + GetResourcePixmapPath(DisplayOfScreen(screen)); + filename = XtFindFile(pixmap_path, sub, XtNumber(sub), NULL); + if (!filename) + return (FALSE); + } + else + filename = params->name; + + if (XReadBitmapFileData(filename, &width, &height, &data, + &hotX, &hotY) == BitmapSuccess) + { + pixmap = XCreatePixmapFromBitmapData(DisplayOfScreen(screen), + RootWindowOfScreen(screen), + (char *)data, + width, height, fg, bg, depth); + if (data) + XFree(data); + *pixmap_return = pixmap; + *mask_return = None; + *width_return = width; + *height_return = height; + + retval = True; + } + + if (filename != params->name) + XtFree(filename); + + return (retval); +} + +#define VERTICAL 1 +#define HORIZONTAL 2 +static Bool +GradientLoader(XawParams *params, Screen *screen, Colormap colormap, int depth, + Pixmap *pixmap_return, Pixmap *mask_return, + Dimension *width_return, Dimension *height_return) +{ + double ired, igreen, iblue, red, green, blue; + XColor start, end, color; + XGCValues values; + GC gc; + double i, inc, x, y, xend, yend; + Pixmap pixmap; + XawArgVal *argval; + int orientation, dimension, steps; + char *value; + + if (XmuCompareISOLatin1(params->name, "vertical") == 0) + orientation = VERTICAL; + else if (XmuCompareISOLatin1(params->name, "horizontal") == 0) + orientation = HORIZONTAL; + else + return (False); + + if ((argval = XawFindArgVal(params, "dimension")) != NULL + && argval->value) + { + dimension = atoi(argval->value); + if (dimension <= 0) + return (False); + } + else + dimension = 50; + + if ((argval = XawFindArgVal(params, "steps")) != NULL + && argval->value) + { + steps = atoi(argval->value); + if (steps <= 0) + return (False); + } + else + steps = dimension; + + steps = XawMin(steps, dimension); + + value = NULL; + if ((argval = XawFindArgVal(params, "start")) != NULL) + value = argval->value; + if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value, + &start, &color)) + return (False); + else if (!value) + { + start.pixel = WhitePixelOfScreen(screen); + XQueryColor(DisplayOfScreen(screen), colormap, &start); + } + value = NULL; + if ((argval = XawFindArgVal(params, "end")) != NULL) + value = argval->value; + if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value, + &end, &color)) + return (False); + else if (!value) + { + end.pixel = BlackPixelOfScreen(screen); + XQueryColor(DisplayOfScreen(screen), colormap, &end); + } + + if ((pixmap = XCreatePixmap(DisplayOfScreen(screen), + RootWindowOfScreen(screen), + orientation == VERTICAL ? 1 : dimension, + orientation == VERTICAL ? dimension : 1, depth)) + == 0) + return (False); + + ired = (double)(end.red - start.red) / (double)steps; + igreen = (double)(end.green - start.green) / (double)steps; + iblue = (double)(end.blue - start.blue) / (double)steps; + + red = color.red = start.red; + green = color.green = start.green; + blue = color.blue = start.blue; + + inc = (double)dimension / (double)steps; + + gc = XCreateGC(DisplayOfScreen(screen), pixmap, 0, &values); + + x = y = 0.0; + if (orientation == VERTICAL) + { + xend = 1; + yend = 0; + } + else + { + xend = 0; + yend = 1; + } + + color.flags = DoRed | DoGreen | DoBlue; + + XSetForeground(DisplayOfScreen(screen), gc, start.pixel); + for (i = 0.0; i < dimension; i += inc) + { + if ((int)color.red != (int)red || (int)color.green != (int)green + || (int)color.blue != (int)blue) + { + XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y, + (unsigned int)xend, (unsigned int)yend); + color.red = (unsigned short)red; + color.green = (unsigned short)green; + color.blue = (unsigned short)blue; + if (!XAllocColor(DisplayOfScreen(screen), colormap, &color)) + { + XFreePixmap(DisplayOfScreen(screen), pixmap); + return (False); + } + XSetForeground(DisplayOfScreen(screen), gc, color.pixel); + if (orientation == VERTICAL) + y = yend; + else + x = xend; + } + red += ired; + green += igreen; + blue += iblue; + if (orientation == VERTICAL) + yend += inc; + else + xend += inc; + } + XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y, + (unsigned int)xend, (unsigned int)yend); + + *pixmap_return = pixmap; + *mask_return = None; + *width_return = orientation == VERTICAL ? 1 : dimension; + *height_return = orientation == VERTICAL ? dimension : 1; + + XFreeGC(DisplayOfScreen(screen), gc); + + return (True); +} + +static Bool +XPixmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth, + Pixmap *pixmap_return, Pixmap *mask_return, + Dimension *width_return, Dimension *height_return) +{ + XpmAttributes xpm_attributes; + XawArgVal *argval; + unsigned int closeness = 4000; + static SubstitutionRec sub[] = { + {'H', NULL}, + {'N', NULL}, + {'T', "pixmaps"}, + {'P', PROJECT_ROOT}, + }; + char *filename; + + if ((argval = XawFindArgVal(params, "closeness")) != NULL + && argval->value) + closeness = atoi(argval->value); + + if (params->name[0] != '/' && params->name[0] != '.') + { + if (!sub[0].substitution) + sub[0].substitution = getenv("HOME"); + sub[1].substitution = params->name; + if (pixmap_path == NULL) + GetResourcePixmapPath(DisplayOfScreen(screen)); + filename = XtFindFile(pixmap_path, sub, XtNumber(sub), NULL); + if (!filename) + return (False); + } + else + filename = params->name; + + xpm_attributes.colormap = colormap; + xpm_attributes.closeness = closeness; + xpm_attributes.valuemask = XpmSize | XpmColormap | XpmCloseness; + if (XpmReadFileToPixmap(DisplayOfScreen(screen), + RootWindowOfScreen(screen), filename, pixmap_return, + mask_return, &xpm_attributes) == XpmSuccess) + { + *width_return = xpm_attributes.width; + *height_return = xpm_attributes.height; + + return (True); + } + + return (False); +} + +void +XawReshapeWidget(Widget w, XawPixmap *pixmap) +{ + if (!pixmap || pixmap->mask == None) + XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0, + None, ShapeSet); + else + XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0, + pixmap->mask, ShapeSet); +} + +#endif /* OLDXAW */ diff --git a/src/Porthole.c b/src/Porthole.c new file mode 100644 index 0000000..4842e70 --- /dev/null +++ b/src/Porthole.c @@ -0,0 +1,376 @@ +/* + * +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + * + * This widget is a trivial clipping widget. It is typically used with a + * panner or scrollbar to navigate. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include "Private.h" + +/* + * Class Methods + */ +static void XawPortholeChangeManaged(Widget); +static XtGeometryResult XawPortholeGeometryManager(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static XtGeometryResult XawPortholeQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawPortholeRealize(Widget, Mask*, XSetWindowAttributes*); +static void XawPortholeResize(Widget); + +/* + * Prototypes + */ +static Widget find_child(PortholeWidget); +static void layout_child(PortholeWidget, Widget, XtWidgetGeometry*, + Position*, Position*, Dimension*, Dimension*); +static void SendReport(PortholeWidget, unsigned int); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(PortholeRec, porthole.field) +static XtResource resources[] = { + { + XtNreportCallback, + XtCReportCallback, + XtRCallback, + sizeof(XtPointer), + offset(report_callbacks), + XtRCallback, + NULL + }, +}; +#undef offset + +#define Superclass (&compositeClassRec) +PortholeClassRec portholeClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "Porthole", /* class_name */ + sizeof(PortholeRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + NULL, /* initialize */ + NULL, /* initialize_hook */ + XawPortholeRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + XawPortholeResize, /* resize */ + NULL, /* expose */ + NULL, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XawPortholeQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* composite */ + { + XawPortholeGeometryManager, /* geometry_manager */ + XawPortholeChangeManaged, /* change_managed */ + XtInheritInsertChild, /* insert_child */ + XtInheritDeleteChild, /* delete_child */ + NULL, /* extension */ + }, + { /* porthole */ + NULL, /* extension */ + }, +}; + +WidgetClass portholeWidgetClass = (WidgetClass)&portholeClassRec; + +/* + * Implementation + */ +static Widget +find_child(PortholeWidget pw) +{ + Widget *children; + unsigned int i; + + /* + * Find the managed child on which we should operate. Ignore multiple + * managed children + */ + for (i = 0, children = pw->composite.children; + i < pw->composite.num_children; i++, children++) + if (XtIsManaged(*children)) + return (*children); + + return (NULL); +} + +static void +SendReport(PortholeWidget pw, unsigned int changed) +{ + Widget child = find_child(pw); + + if (pw->porthole.report_callbacks && child) { + XawPannerReport prep; + + prep.changed = changed; + prep.slider_x = -XtX(child); /* porthole is "inner" */ + prep.slider_y = -XtY(child); /* child is outer since it is larger */ + prep.slider_width = XtWidth(pw); + prep.slider_height = XtHeight(pw); + prep.canvas_width = XtWidth(child); + prep.canvas_height = XtHeight(child); + XtCallCallbackList((Widget)pw, pw->porthole.report_callbacks, + (XtPointer)&prep); + } +} + +static void +layout_child(PortholeWidget pw, Widget child, XtWidgetGeometry *geomp, + Position *xp, Position *yp, Dimension *widthp, Dimension *heightp) +{ + Position minx, miny; + + *xp = XtX(child); /* default to current values */ + *yp = XtY(child); + *widthp = XtWidth(child); + *heightp = XtHeight(child); + if (geomp) { /* mix in any requested changes */ + if (geomp->request_mode & CWX) + *xp = geomp->x; + if (geomp->request_mode & CWY) + *yp = geomp->y; + if (geomp->request_mode & CWWidth) + *widthp = geomp->width; + if (geomp->request_mode & CWHeight) + *heightp = geomp->height; + } + + /* + * Make sure that the child is at least as large as the porthole; there + * is no maximum size + */ + if (*widthp < XtWidth(pw)) *widthp = XtWidth(pw); + if (*heightp < XtHeight(pw)) *heightp = XtHeight(pw); + + /* + * Make sure that the child is still on the screen. Note that this must + * be done *after* the size computation so that we know where to put it + */ + minx = (Position)XtWidth(pw) - (Position)*widthp; + miny = (Position)XtHeight(pw) - (Position)*heightp; + + if (*xp < minx) + *xp = minx; + if (*yp < miny) + *yp = miny; + + if (*xp > 0) + *xp = 0; + if (*yp > 0) + *yp = 0; +} + +static void +XawPortholeRealize(Widget gw, Mask *valueMask, XSetWindowAttributes *attr) +{ + attr->bit_gravity = NorthWestGravity; + *valueMask |= CWBitGravity; + + if (XtWidth(gw) < 1) + XtWidth(gw) = 1; + if (XtHeight(gw) < 1) + XtHeight(gw) = 1; + (*portholeWidgetClass->core_class.superclass->core_class.realize) + (gw, valueMask, attr); +} + +static void +XawPortholeResize(Widget gw) +{ + PortholeWidget pw = (PortholeWidget)gw; + Widget child = find_child(pw); + + /* + * If we have a child, we need to make sure that it is at least as big + * as we are and in the right place + */ + if (child) { + Position x, y; + Dimension width, height; + + layout_child(pw, child, NULL, &x, &y, &width, &height); + XtConfigureWidget(child, x, y, width, height, 0); + } + + SendReport(pw, XawPRCanvasWidth | XawPRCanvasHeight); +} + +static XtGeometryResult +XawPortholeQueryGeometry(Widget gw, XtWidgetGeometry *intended, + XtWidgetGeometry *preferred) +{ + PortholeWidget pw = (PortholeWidget)gw; + Widget child = find_child(pw); + + if (child) { +#define SIZEONLY (CWWidth | CWHeight) + preferred->request_mode = SIZEONLY; + preferred->width = XtWidth(child); + preferred->height = XtHeight(child); + + if ((intended->request_mode & SIZEONLY) == SIZEONLY && + intended->width == preferred->width && + intended->height == preferred->height) + return (XtGeometryYes); + else if (preferred->width == XtWidth(pw) && + preferred->height == XtHeight(pw)) + return (XtGeometryNo); + + return (XtGeometryAlmost); +#undef SIZEONLY + } + + return (XtGeometryNo); +} + +static XtGeometryResult +XawPortholeGeometryManager(Widget w, XtWidgetGeometry *req, + XtWidgetGeometry *reply) +{ + PortholeWidget pw = (PortholeWidget) w->core.parent; + Widget child = find_child(pw); + Bool okay = True; + + if (child != w) + return (XtGeometryNo); + + *reply = *req; /* assume we'll grant everything */ + + if ((req->request_mode & CWBorderWidth) && req->border_width != 0) { + reply->border_width = 0; + okay = False; + } + + layout_child(pw, child, req, &reply->x, &reply->y, + &reply->width, &reply->height); + + if ((req->request_mode & CWX) && req->x != reply->x) + okay = False; + if ((req->request_mode & CWY) && req->x != reply->x) + okay = False; + if ((req->request_mode & CWWidth) && req->width != reply->width) + okay = False; + if ((req->request_mode & CWHeight) && req->height != reply->height) + okay = False; + + /* + * If we failed on anything, simply return without touching widget + */ + if (!okay) + return (XtGeometryAlmost); + + /* + * If not just doing a query, update widget and send report. Note that + * we will often set fields that weren't requested because we want to keep + * the child visible + */ + if (!(req->request_mode & XtCWQueryOnly)) { + unsigned int changed = 0; + + if (XtX(child) != reply->x) { + changed |= XawPRSliderX; + XtX(child) = reply->x; + } + if (XtY(child) != reply->y) { + changed |= XawPRSliderY; + XtY(child) = reply->y; + } + if (XtWidth(child) != reply->width) { + changed |= XawPRSliderWidth; + XtWidth(child) = reply->width; + } + if (XtHeight(child) != reply->height) { + changed |= XawPRSliderHeight; + XtHeight(child) = reply->height; + } + if (changed) + SendReport(pw, changed); + } + + return (XtGeometryYes); /* success! */ +} + +static void +XawPortholeChangeManaged(Widget gw) +{ + PortholeWidget pw = (PortholeWidget)gw; + Widget child = find_child (pw); /* ignore extra children */ + + if (child) { + if (!XtIsRealized (gw)) { + XtWidgetGeometry geom, retgeom; + + geom.request_mode = 0; + if (XtWidth(pw) == 0) { + geom.width = XtWidth(child); + geom.request_mode |= CWWidth; + } + if (XtHeight(pw) == 0) { + geom.height = XtHeight(child); + geom.request_mode |= CWHeight; + } + if (geom.request_mode && + XtMakeGeometryRequest (gw, &geom, &retgeom) + == XtGeometryAlmost) + (void)XtMakeGeometryRequest(gw, &retgeom, NULL); + } + + XtResizeWidget(child, Max(XtWidth(child), XtWidth(pw)), + Max(XtHeight(child), XtHeight(pw)), 0); + + SendReport(pw, XawPRAll); + } +} diff --git a/src/Private.h b/src/Private.h new file mode 100644 index 0000000..ca70d5f --- /dev/null +++ b/src/Private.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1998 by The XFree86 Project, Inc. + * + * 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 XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#ifndef _XawPrivate_h +#define _XawPrivate_h + +#define XawMax(a, b) ((a) > (b) ? (a) : (b)) +#define XawMin(a, b) ((a) < (b) ? (a) : (b)) +#define XawAbs(a) ((a) < 0 ? -(a) : (a)) + +#define XawStackAlloc(size, stk_buffer) \ +((size) <= sizeof(stk_buffer) \ + ? (XtPointer)(stk_buffer) \ + : XtMalloc((unsigned)(size))) + +#define XawStackFree(pointer, stk_buffer) \ +do { \ + if ((pointer) != (XtPointer)(stk_buffer)) \ + XtFree((char *)pointer); \ +} while (0) + +#ifndef XtX +#define XtX(w) (((RectObj)w)->rectangle.x) +#endif +#ifndef XtY +#define XtY(w) (((RectObj)w)->rectangle.y) +#endif +#ifndef XtWidth +#define XtWidth(w) (((RectObj)w)->rectangle.width) +#endif +#ifndef XtHeight +#define XtHeight(w) (((RectObj)w)->rectangle.height) +#endif +#ifndef XtBorderWidth +#define XtBorderWidth(w) (((RectObj)w)->rectangle.border_width) +#endif + +#ifndef OLDXAW +#define XAW_PRIV_VAR_PREFIX '$' + +typedef Bool (*XawParseBooleanProc)(Widget, String, XEvent*, Bool*); + +typedef struct _XawActionVarList XawActionVarList; +typedef struct _XawActionResList XawActionResList; + +/* Boolean expressions */ +Bool XawParseBoolean(Widget, String, XEvent*, Bool*); +Bool XawBooleanExpression(Widget, String, XEvent*); + +/* actions */ +void XawPrintActionErrorMsg(String, Widget, String*, Cardinal*); +XawActionResList *XawGetActionResList(WidgetClass); +XawActionVarList *XawGetActionVarList(Widget); + +void XawSetValuesAction(Widget, XEvent*, String*, Cardinal*); +void XawGetValuesAction(Widget, XEvent*, String*, Cardinal*); +void XawDeclareAction(Widget, XEvent*, String*, Cardinal*); +void XawCallProcAction(Widget, XEvent*, String*, Cardinal*); + +/* display lists */ +#define XAWDL_CONVERT_ERROR (XtPointer)-1 +typedef struct _XawDL _XawDisplayList; +typedef struct _XawDLClass XawDLClass, XawDisplayListClass; + +typedef void (*XawDisplayListProc)(Widget, XtPointer, XtPointer, + XEvent*, Region); +typedef void *(*XawDLArgsInitProc)(String, String*, Cardinal*, + Screen*, Colormap, int); +typedef void *(*XawDLDataInitProc)(String, + Screen*, Colormap, int); +typedef void (*XawDLArgsDestructor)(Display*, String, XtPointer, + String*, Cardinal*); +typedef void (*XawDLDataDestructor)(Display*, String, XtPointer); + +void XawRunDisplayList(Widget, _XawDisplayList*, XEvent*, Region); +void XawDisplayListInitialize(void); + +_XawDisplayList *XawCreateDisplayList(String, Screen*, Colormap, int); +void XawDestroyDisplayList(_XawDisplayList*); +String XawDisplayListString(_XawDisplayList*); +XawDLClass *XawGetDisplayListClass(String); +XawDLClass *XawCreateDisplayListClass(String, + XawDLArgsInitProc, XawDLArgsDestructor, + XawDLDataInitProc, XawDLDataDestructor); +Bool XawDeclareDisplayListProc(XawDLClass*, String, XawDisplayListProc); + +/* pixmaps */ +typedef struct _XawArgVal { + String name; + String value; +} XawArgVal; + +typedef struct _XawParams { + String name; + String type; + String ext; + XawArgVal **args; + Cardinal num_args; +} XawParams; + +typedef struct _XawPixmap { + String name; + Pixmap pixmap; + Pixmap mask; + Dimension width; + Dimension height; +} XawPixmap; + +typedef Bool (*XawPixmapLoader)(XawParams*, Screen*, Colormap, int, + Pixmap*, Pixmap*, + Dimension*, Dimension*); +Bool XawPixmapsInitialize(void); +Bool XawAddPixmapLoader(String, String, XawPixmapLoader); +XawPixmap *XawLoadPixmap(String, Screen*, Colormap, int); +XawPixmap *XawPixmapFromXPixmap(Pixmap, Screen*, Colormap, int); +XawParams *XawParseParamsString(String name); +void XawFreeParamsStruct(XawParams *params); +XawArgVal *XawFindArgVal(XawParams *params, String name); +void XawReshapeWidget(Widget, XawPixmap*); +#endif /* OLDXAW */ + +/* misc */ +void XawTypeToStringWarning(Display*, String); + +/* OS.c */ +int _XawGetPageSize(void); + +#endif /* _XawPrivate_h */ diff --git a/src/Repeater.c b/src/Repeater.c new file mode 100644 index 0000000..9b16ced --- /dev/null +++ b/src/Repeater.c @@ -0,0 +1,298 @@ +/* + * +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + * + * This widget is used for press-and-hold style buttons. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include + +#define DO_CALLBACK(rw) \ +XtCallCallbackList((Widget)rw, rw->command.callbacks, NULL) + +#define ADD_TIMEOUT(rw, delay) \ +XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)rw), \ + delay, tic, (XtPointer)rw) + +#define CLEAR_TIMEOUT(rw) \ +if ((rw)->repeater.timer) { \ + XtRemoveTimeOut((rw)->repeater.timer); \ + (rw)->repeater.timer = 0; \ +} + +/* + * Class Methods + */ +static void XawRepeaterInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawRepeaterDestroy(Widget); +static Boolean XawRepeaterSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * Prototypes + */ +static void tic(XtPointer, XtIntervalId*); + +/* + * Actions + */ +static void ActionStart(Widget, XEvent*, String*, Cardinal*); +static void ActionStop(Widget, XEvent*, String*, Cardinal*); + +/* + * Initialization + */ +static char defaultTranslations[] = +":" "highlight()\n" +":" "unhighlight()\n" +":" "set() start()\n" +":" "stop() unset()\n" +; + +static XtActionsRec actions[] = { + {"start", ActionStart}, + {"stop", ActionStop}, +}; + +#define offset(field) XtOffsetOf(RepeaterRec, repeater.field) +static XtResource resources[] = { + { + XtNdecay, + XtCDecay, + XtRInt, + sizeof(int), + offset(decay), + XtRImmediate, + (XtPointer)REP_DEF_DECAY + }, + { + XtNinitialDelay, + XtCDelay, + XtRInt, + sizeof(int), + offset(initial_delay), + XtRImmediate, + (XtPointer)REP_DEF_INITIAL_DELAY + }, + { + XtNminimumDelay, + XtCMinimumDelay, + XtRInt, + sizeof(int), + offset(minimum_delay), + XtRImmediate, + (XtPointer)REP_DEF_MINIMUM_DELAY + }, + { + XtNrepeatDelay, + XtCDelay, + XtRInt, + sizeof(int), + offset(repeat_delay), + XtRImmediate, + (XtPointer)REP_DEF_REPEAT_DELAY + }, + { + XtNflash, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(flash), + XtRImmediate, + (XtPointer)False + }, + { + XtNstartCallback, + XtCStartCallback, + XtRCallback, + sizeof(XtPointer), + offset(start_callbacks), + XtRImmediate, + NULL + }, + { + XtNstopCallback, + XtCStopCallback, + XtRCallback, + sizeof(XtPointer), + offset(stop_callbacks), + XtRImmediate, + NULL + }, +}; +#undef offset + +#define Superclass (&commandClassRec) +RepeaterClassRec repeaterClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "Repeater", /* class_name */ + sizeof(RepeaterRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawRepeaterInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + actions, /* actions */ + XtNumber(actions), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawRepeaterDestroy, /* destroy */ + XtInheritResize, /* resize */ + XtInheritExpose, /* expose */ + XawRepeaterSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + defaultTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* label */ + { + NULL, /* extension */ + }, + /* command */ + { + NULL, /* extension */ + }, + /* repeater */ + { + NULL, /* extension */ + }, +}; + +WidgetClass repeaterWidgetClass = (WidgetClass) &repeaterClassRec; + + +/* + * Implementation + */ +/*ARGSUSED*/ +static void +tic(XtPointer client_data, XtIntervalId *id) +{ + RepeaterWidget rw = (RepeaterWidget)client_data; + + rw->repeater.timer = 0; /* timer is removed */ + if (rw->repeater.flash) { + Widget w = (Widget)rw; + + XClearWindow(XtDisplay(w), XtWindow(w)); + XtCallActionProc(w, "reset", NULL, NULL, 0); + XClearWindow(XtDisplay(w), XtWindow(w)); + XtCallActionProc(w, "set", NULL, NULL, 0); + } + DO_CALLBACK(rw); + + rw->repeater.timer = ADD_TIMEOUT(rw, rw->repeater.next_delay); + + if (rw->repeater.decay) { + rw->repeater.next_delay -= rw->repeater.decay; + if (rw->repeater.next_delay < rw->repeater.minimum_delay) + rw->repeater.next_delay = rw->repeater.minimum_delay; + } +} + +/*ARGSUSED*/ +static void +XawRepeaterInitialize(Widget greq, Widget gnew, + ArgList args, Cardinal *num_args) +{ + RepeaterWidget cnew = (RepeaterWidget)gnew; + + if (cnew->repeater.minimum_delay < 0) + cnew->repeater.minimum_delay = 0; + cnew->repeater.timer = 0; +} + +static void +XawRepeaterDestroy(Widget gw) +{ + CLEAR_TIMEOUT((RepeaterWidget)gw); +} + +/*ARGSUSED*/ +static Boolean +XawRepeaterSetValues(Widget gcur, Widget greq, Widget gnew, + ArgList args, Cardinal *num_args) +{ + RepeaterWidget cur = (RepeaterWidget)gcur; + RepeaterWidget cnew = (RepeaterWidget)gnew; + + if (cur->repeater.minimum_delay != cnew->repeater.minimum_delay) { + if (cnew->repeater.next_delay < cnew->repeater.minimum_delay) + cnew->repeater.next_delay = cnew->repeater.minimum_delay; + } + + return (False); +} + +/*ARGSUSED*/ +static void +ActionStart(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + RepeaterWidget rw = (RepeaterWidget)gw; + + CLEAR_TIMEOUT(rw); + if (rw->repeater.start_callbacks) + XtCallCallbackList(gw, rw->repeater.start_callbacks, NULL); + + DO_CALLBACK(rw); + rw->repeater.timer = ADD_TIMEOUT(rw, rw->repeater.initial_delay); + rw->repeater.next_delay = rw->repeater.repeat_delay; +} + +/*ARGSUSED*/ +static void +ActionStop(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + RepeaterWidget rw = (RepeaterWidget)gw; + + CLEAR_TIMEOUT((RepeaterWidget)gw); + if (rw->repeater.stop_callbacks) + XtCallCallbackList(gw, rw->repeater.stop_callbacks, NULL); +} diff --git a/src/Scrollbar.c b/src/Scrollbar.c new file mode 100644 index 0000000..894a945 --- /dev/null +++ b/src/Scrollbar.c @@ -0,0 +1,882 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include "Private.h" + +#define NoButton -1 +#define PICKLENGTH(widget, x, y) \ +(((widget)->scrollbar.orientation == XtorientHorizontal) ? (x) : (y)) + +/* + * Class Methods + */ +static void XawScrollbarClassInitialize(void); +static void XawScrollbarDestroy(Widget); +static void XawScrollbarInitialize(Widget, Widget, ArgList, Cardinal*_args); +static void XawScrollbarRealize(Widget, Mask*, XSetWindowAttributes*); +static void XawScrollbarRedisplay(Widget, XEvent*, Region); +static void XawScrollbarResize(Widget); +static Boolean XawScrollbarSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * Prototypes + */ +static Boolean CompareEvents(XEvent*, XEvent*); +static void CreateGC(Widget); +static float FloatInRange(float, float, float); +static float FractionLoc(ScrollbarWidget, int, int); +static void ExtractPosition(XEvent*, Position*, Position*); +static int InRange(int, int, int); +static void FillArea(ScrollbarWidget, int, int, int); +static Bool LookAhead(Widget, XEvent*); +static void PaintThumb(ScrollbarWidget); +static Bool PeekNotifyEvent(Display*, XEvent*, char*); +static void SetDimensions(ScrollbarWidget); + +/* + * Actions + */ +static void EndScroll(Widget, XEvent*, String*, Cardinal*); +static void MoveThumb(Widget, XEvent*, String*, Cardinal*); +static void NotifyScroll(Widget, XEvent*, String*, Cardinal*); +static void NotifyThumb(Widget, XEvent*, String*, Cardinal*); +static void StartScroll(Widget, XEvent*, String*, Cardinal*); + +/* + * Initialization + */ +static char defaultTranslations[] = +":" "StartScroll(Forward)\n" +":" "StartScroll(Continuous) MoveThumb() NotifyThumb()\n" +":" "StartScroll(Backward)\n" +":" "MoveThumb() NotifyThumb()\n" +":" "NotifyScroll(Proportional) EndScroll()\n"; + +static float floatZero = 0.0; + +#define Offset(field) XtOffsetOf(ScrollbarRec, field) + +static XtResource resources[] = { + { + XtNlength, + XtCLength, + XtRDimension, + sizeof(Dimension), + Offset(scrollbar.length), + XtRImmediate, + (XtPointer)1 + }, + { + XtNthickness, + XtCThickness, + XtRDimension, + sizeof(Dimension), + Offset(scrollbar.thickness), + XtRImmediate, + (XtPointer)14 + }, + { + XtNorientation, + XtCOrientation, + XtROrientation, + sizeof(XtOrientation), + Offset(scrollbar.orientation), + XtRImmediate, + (XtPointer)XtorientVertical + }, + { + XtNscrollProc, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + Offset(scrollbar.scrollProc), + XtRCallback, + NULL + }, + { + XtNthumbProc, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + Offset(scrollbar.thumbProc), + XtRCallback, + NULL + }, + { + XtNjumpProc, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + Offset(scrollbar.jumpProc), + XtRCallback, + NULL + }, + { + XtNthumb, + XtCThumb, + XtRBitmap, + sizeof(Pixmap), + Offset(scrollbar.thumb), + XtRImmediate, + (XtPointer)XtUnspecifiedPixmap + }, + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + Offset(scrollbar.foreground), + XtRString, + XtDefaultForeground + }, + { + XtNshown, + XtCShown, + XtRFloat, + sizeof(float), + Offset(scrollbar.shown), + XtRFloat, + (XtPointer)&floatZero + }, + { + XtNtopOfThumb, + XtCTopOfThumb, + XtRFloat, + sizeof(float), + Offset(scrollbar.top), + XtRFloat, + (XtPointer)&floatZero + }, + { + XtNscrollVCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + Offset(scrollbar.verCursor), + XtRString, + "sb_v_double_arrow" + }, + { + XtNscrollHCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + Offset(scrollbar.horCursor), + XtRString, + "sb_h_double_arrow" + }, + { + XtNscrollUCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + Offset(scrollbar.upCursor), + XtRString, + "sb_up_arrow" + }, + { + XtNscrollDCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + Offset(scrollbar.downCursor), + XtRString, + "sb_down_arrow" + }, + { + XtNscrollLCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + Offset(scrollbar.leftCursor), + XtRString, + "sb_left_arrow" + }, + { + XtNscrollRCursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + Offset(scrollbar.rightCursor), + XtRString, + "sb_right_arrow" + }, + { + XtNminimumThumb, + XtCMinimumThumb, + XtRDimension, + sizeof(Dimension), + Offset(scrollbar.min_thumb), + XtRImmediate, + (XtPointer)7 + }, +}; +#undef Offset + +static XtActionsRec actions[] = { + {"StartScroll", StartScroll}, + {"MoveThumb", MoveThumb}, + {"NotifyThumb", NotifyThumb}, + {"NotifyScroll", NotifyScroll}, + {"EndScroll", EndScroll}, +}; + +#define Superclass (&simpleClassRec) +ScrollbarClassRec scrollbarClassRec = { + /* core */ + { + (WidgetClass)&simpleClassRec, /* superclass */ + "Scrollbar", /* class_name */ + sizeof(ScrollbarRec), /* widget_size */ + XawScrollbarClassInitialize, /* class_initialize */ + NULL, /* class_part_init */ + False, /* class_inited */ + XawScrollbarInitialize, /* initialize */ + NULL, /* initialize_hook */ + XawScrollbarRealize, /* realize */ + actions, /* actions */ + XtNumber(actions), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawScrollbarDestroy, /* destroy */ + XawScrollbarResize, /* resize */ + XawScrollbarRedisplay, /* expose */ + XawScrollbarSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + defaultTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* scrollbar */ + { + NULL, /* extension */ + }, +}; + +WidgetClass scrollbarWidgetClass = (WidgetClass)&scrollbarClassRec; + +/* + * Implementation + */ +static void +XawScrollbarClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtAddConverter(XtRString, XtROrientation, XmuCvtStringToOrientation, + NULL, 0); + XtSetTypeConverter(XtROrientation, XtRString, XmuCvtOrientationToString, + NULL, 0, XtCacheNone, NULL); +} + +/* + * Make sure the first number is within the range specified by the other + * two numbers. + */ +static int +InRange(int num, int small, int big) +{ + return ((num < small) ? small : ((num > big) ? big : num)); +} + +/* + * Same as above, but for floating numbers + */ +static float +FloatInRange(float num, float small, float big) +{ + return ((num < small) ? small : ((num > big) ? big : num)); +} + +/* Fill the area specified by top and bottom with the given pattern */ +static float +FractionLoc(ScrollbarWidget w, int x, int y) +{ + float result; + + result = PICKLENGTH(w, x / (float)XtWidth(w), y / (float)XtHeight(w)); + + return (FloatInRange(result, 0.0, 1.0)); +} + +static void +FillArea(ScrollbarWidget w, int top, int bottom, int thumb) +{ + Dimension length; + + top = XawMax(1, top); + if (w->scrollbar.orientation == XtorientHorizontal) + bottom = XawMin(bottom, XtWidth(w) - 1); + else + bottom = XawMin(bottom, XtHeight(w) - 1); + + if (bottom <= top) + return; + + length = bottom - top; + + switch(thumb) { + /* Fill the new Thumb location */ + case 1: + if (w->scrollbar.orientation == XtorientHorizontal) + XFillRectangle(XtDisplay(w), XtWindow(w), w->scrollbar.gc, + top, 1, length, XtHeight(w) - 2); + else + XFillRectangle(XtDisplay(w), XtWindow(w), w->scrollbar.gc, + 1, top, XtWidth(w) - 2, length); + break; + /* Clear the old Thumb location */ + case 0: + if (w->scrollbar.orientation == XtorientHorizontal) + XClearArea(XtDisplay(w), XtWindow(w), + top, 1, length, XtHeight(w) - 2, False); + else + XClearArea(XtDisplay(w), XtWindow(w), + 1, top, XtWidth(w) - 2, length, False); + break; + } +} + + +/* Paint the thumb in the area specified by w->top and + w->shown. The old area is erased. The painting and + erasing is done cleverly so that no flickering will occur. */ +static void +PaintThumb(ScrollbarWidget w) +{ + Position oldtop, oldbot, newtop, newbot; + + oldtop = w->scrollbar.topLoc; + oldbot = oldtop + w->scrollbar.shownLength; + newtop = w->scrollbar.length * w->scrollbar.top; + newbot = newtop + (int)(w->scrollbar.length * w->scrollbar.shown); + if (newbot < newtop + (int)w->scrollbar.min_thumb) + newbot = newtop + w->scrollbar.min_thumb; + w->scrollbar.topLoc = newtop; + w->scrollbar.shownLength = newbot - newtop; + + if (XtIsRealized((Widget)w)) { + if (newtop < oldtop) + FillArea(w, newtop, XawMin(newbot, oldtop), 1); + if (newtop > oldtop) + FillArea(w, oldtop, XawMin(newtop, oldbot), 0); + if (newbot < oldbot) + FillArea(w, XawMax(newbot, oldtop), oldbot, 0); + if (newbot > oldbot) + FillArea(w, XawMax(newtop, oldbot), newbot, 1); + } +} + +static void +SetDimensions(ScrollbarWidget w) +{ + if (w->scrollbar.orientation == XtorientVertical) { + w->scrollbar.length = XtHeight(w); + w->scrollbar.thickness = XtWidth(w); + } + else { + w->scrollbar.length = XtWidth(w); + w->scrollbar.thickness = XtHeight(w); + } +} + +static void +XawScrollbarDestroy(Widget w) +{ + ScrollbarWidget sbw = (ScrollbarWidget)w; + + XtReleaseGC(w, sbw->scrollbar.gc); +} + +static void +CreateGC(Widget w) +{ + ScrollbarWidget sbw = (ScrollbarWidget)w; + XGCValues gcValues; + XtGCMask mask; + unsigned int depth = 1; + + if (sbw->scrollbar.thumb == XtUnspecifiedPixmap) + sbw->scrollbar.thumb = XmuCreateStippledPixmap(XtScreen(w), + (Pixel)1, (Pixel)0, + depth); + else if (sbw->scrollbar.thumb != None) { + Window root; + int x, y; + unsigned int width, height, bw; + + XGetGeometry(XtDisplay(w), sbw->scrollbar.thumb, &root, &x, &y, + &width, &height, &bw, &depth); + } + + gcValues.foreground = sbw->scrollbar.foreground; + gcValues.background = sbw->core.background_pixel; + mask = GCForeground | GCBackground; + + if (sbw->scrollbar.thumb != None) { + if (depth == 1) { + gcValues.fill_style = FillOpaqueStippled; + gcValues.stipple = sbw->scrollbar.thumb; + mask |= GCFillStyle | GCStipple; + } + else { + gcValues.fill_style = FillTiled; + gcValues.tile = sbw->scrollbar.thumb; + mask |= GCFillStyle | GCTile; + } + } + sbw->scrollbar.gc = XtGetGC(w, mask, &gcValues); +} + +/* ARGSUSED */ +static void +XawScrollbarInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + ScrollbarWidget w = (ScrollbarWidget)cnew; + + CreateGC(cnew); + + if (XtWidth(w) == 0) + XtWidth(w) = w->scrollbar.orientation == XtorientVertical ? + w->scrollbar.thickness : w->scrollbar.length; + + if (XtHeight(w) == 0) + XtHeight(w) = w->scrollbar.orientation == XtorientHorizontal ? + w->scrollbar.thickness : w->scrollbar.length; + + SetDimensions(w); + w->scrollbar.direction = 0; + w->scrollbar.topLoc = 0; + w->scrollbar.shownLength = w->scrollbar.min_thumb; +} + +static void +XawScrollbarRealize(Widget gw, Mask *valueMask, + XSetWindowAttributes *attributes) +{ + ScrollbarWidget w = (ScrollbarWidget)gw; + + w->scrollbar.inactiveCursor = w->scrollbar.orientation == XtorientVertical ? + w->scrollbar.verCursor : w->scrollbar.horCursor; + + XtVaSetValues(gw, XtNcursor, w->scrollbar.inactiveCursor, NULL); + + /* + * The Simple widget actually stuffs the value in the valuemask + */ + (*scrollbarWidgetClass->core_class.superclass->core_class.realize) + (gw, valueMask, attributes); +} + +/*ARGSUSED*/ +static Boolean +XawScrollbarSetValues(Widget current, Widget request, Widget desired, + ArgList args, Cardinal *num_args) +{ + ScrollbarWidget w = (ScrollbarWidget)current; + ScrollbarWidget dw = (ScrollbarWidget)desired; + Boolean redraw = False; + + /* + * If these values are outside the acceptable range ignore them... + */ + if (dw->scrollbar.top < 0.0 || dw->scrollbar.top > 1.0) + dw->scrollbar.top = w->scrollbar.top; + + if (dw->scrollbar.shown < 0.0 || dw->scrollbar.shown > 1.0) + dw->scrollbar.shown = w->scrollbar.shown; + + if (XtIsRealized (desired)) { + if (w->scrollbar.foreground != dw->scrollbar.foreground || + w->core.background_pixel != dw->core.background_pixel || + w->scrollbar.thumb != dw->scrollbar.thumb) { + XtReleaseGC((Widget)dw, w->scrollbar.gc); + CreateGC((Widget)dw); + redraw = True; + } + if (w->scrollbar.top != dw->scrollbar.top || + w->scrollbar.shown != dw->scrollbar.shown) + redraw = True; + } + + return (redraw); +} + +static void +XawScrollbarResize(Widget gw) +{ + /* ForgetGravity has taken care of background, but thumb may + * have to move as a result of the new size. */ + SetDimensions((ScrollbarWidget)gw); + XawScrollbarRedisplay(gw, NULL, NULL); +} + +/*ARGSUSED*/ +static void +XawScrollbarRedisplay(Widget gw, XEvent *event, Region region) +{ + ScrollbarWidget w = (ScrollbarWidget)gw; + int x, y; + unsigned int width, height; + + if (Superclass->core_class.expose) + (*Superclass->core_class.expose)(gw, event, region); + + if (w->scrollbar.orientation == XtorientHorizontal) { + x = w->scrollbar.topLoc; + y = 1; + width = w->scrollbar.shownLength; + height = XtHeight(w) - 2; + } + else { + x = 1; + y = w->scrollbar.topLoc; + width = XtWidth(w) - 2; + height = w->scrollbar.shownLength; + } + + if (region == NULL || + XRectInRegion(region, x, y, width, height) != RectangleOut) { + /* Forces entire thumb to be painted */ + w->scrollbar.topLoc = -(w->scrollbar.length + 1); + PaintThumb(w); + } +} + +/*ARGSUSED*/ +static void +StartScroll(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + ScrollbarWidget w = (ScrollbarWidget)gw; + Cursor cursor; + char direction; + + if (w->scrollbar.direction != 0) /* if we're already scrolling */ + return; + if (*num_params > 0) + direction = *params[0]; + else + direction = 'C'; + + w->scrollbar.direction = direction; + + switch(direction) { + case 'B': + case 'b': + cursor = w->scrollbar.orientation == XtorientVertical ? + w->scrollbar.downCursor : w->scrollbar.rightCursor; + break; + case 'F': + case 'f': + cursor = w->scrollbar.orientation == XtorientVertical ? + w->scrollbar.upCursor : w->scrollbar.leftCursor; + break; + case 'C': + case 'c': + cursor = w->scrollbar.orientation == XtorientVertical ? + w->scrollbar.rightCursor : w->scrollbar.upCursor; + break; + default: + return; /* invalid invocation */ + } + + XtVaSetValues(gw, XtNcursor, cursor, NULL); + + XFlush(XtDisplay(w)); +} + +static Boolean +CompareEvents(XEvent *oldEvent, XEvent *newEvent) +{ +#define Check(field) if (newEvent->field != oldEvent->field) return (False) + + Check(xany.display); + Check(xany.type); + Check(xany.window); + + switch(newEvent->type) { + case MotionNotify: + Check(xmotion.state); + break; + case ButtonPress: + case ButtonRelease: + Check(xbutton.state); + Check(xbutton.button); + break; + case KeyPress: + case KeyRelease: + Check(xkey.state); + Check(xkey.keycode); + break; + case EnterNotify: + case LeaveNotify: + Check(xcrossing.mode); + Check(xcrossing.detail); + Check(xcrossing.state); + break; + } +#undef Check + + return (True); +} + +struct EventData { + XEvent *oldEvent; + int count; +}; + +static Bool +PeekNotifyEvent(Display *dpy, XEvent *event, char *args) +{ + struct EventData *eventData = (struct EventData*)args; + + return (++eventData->count == QLength(dpy) /* since PeekIf blocks */ + || CompareEvents(event, eventData->oldEvent)); +} + +static Bool +LookAhead(Widget w, XEvent *event) +{ + XEvent newEvent; + struct EventData eventData; + + if (QLength(XtDisplay(w)) == 0) + return (False); + + eventData.count = 0; + eventData.oldEvent = event; + + XPeekIfEvent(XtDisplay(w), &newEvent, PeekNotifyEvent, (char*)&eventData); + + if (CompareEvents(event, &newEvent)) + return (True); + + return (False); +} + +static void +ExtractPosition(XEvent *event, Position *x, Position *y) +{ + switch(event->type) { + case MotionNotify: + *x = event->xmotion.x; + *y = event->xmotion.y; + break; + case ButtonPress: + case ButtonRelease: + *x = event->xbutton.x; + *y = event->xbutton.y; + break; + case KeyPress: + case KeyRelease: + *x = event->xkey.x; + *y = event->xkey.y; + break; + case EnterNotify: + case LeaveNotify: + *x = event->xcrossing.x; + *y = event->xcrossing.y; + break; + default: + *x = 0; + *y = 0; + break; + } +} + +static void +NotifyScroll(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + ScrollbarWidget w = (ScrollbarWidget)gw; + long call_data = 0; + char style; + Position x, y; + + if (w->scrollbar.direction == 0) /* if no StartScroll */ + return; + + if (LookAhead(gw, event)) + return; + + if (*num_params > 0) + style = *params[0]; + else + style = 'P'; + + switch(style) { + case 'P': /* Proportional */ + case 'p': + ExtractPosition(event, &x, &y); + call_data = InRange(PICKLENGTH(w, x, y), 0, (int)w->scrollbar.length); + break; + case 'F': /* FullLength */ + case 'f': + call_data = w->scrollbar.length; + break; + } + + switch(w->scrollbar.direction) { + case 'B': + case 'b': + call_data = -call_data; + /*FALLTHROUGH*/ + case 'F': + case 'f': + XtCallCallbacks(gw, XtNscrollProc, (XtPointer)call_data); + break; + case 'C': + case 'c': /* NotifyThumb has already called the thumbProc(s) */ + break; + } +} + +/*ARGSUSED*/ +static void +EndScroll(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + ScrollbarWidget w = (ScrollbarWidget)gw; + + XtVaSetValues(gw, XtNcursor, w->scrollbar.inactiveCursor, NULL); + XFlush(XtDisplay(w)); /* make sure it get propogated */ + + w->scrollbar.direction = 0; +} + +/*ARGSUSED*/ +static void +MoveThumb(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + ScrollbarWidget w = (ScrollbarWidget)gw; + Position x, y; + + if (w->scrollbar.direction == 0) /* if no StartScroll */ + return; + + if (LookAhead(gw, event)) + return; + + if (!event->xmotion.same_screen) + return; + + ExtractPosition(event, &x, &y); + w->scrollbar.top = FractionLoc(w, x, y); +} + +/*ARGSUSED*/ +static void +NotifyThumb(Widget gw, XEvent *event, String *params, Cardinal *num_params) +{ + ScrollbarWidget w = (ScrollbarWidget)gw; + union { + XtPointer xtp; + float xtf; + } xtpf; + + if (w->scrollbar.direction == 0) /* if no StartScroll */ + return; + + if (LookAhead(gw, event)) + return; + + /* thumbProc is not pretty, but is necessary for backwards + compatibility on those architectures for which it work{s,ed}; + the intent is to pass a (truncated) float by value. */ + xtpf.xtf = w->scrollbar.top; + XtCallCallbacks(gw, XtNthumbProc, xtpf.xtp); + XtCallCallbacks(gw, XtNjumpProc, (XtPointer)&w->scrollbar.top); + + PaintThumb(w); +} + +/* + * Public routines + */ +/* Set the scroll bar to the given location. */ +void +XawScrollbarSetThumb(Widget gw, +#if NeedWidePrototypes + double top, double shown +#else + float top, float shown +#endif + ) +{ + ScrollbarWidget w = (ScrollbarWidget)gw; + + if (w->scrollbar.direction == 'c') /* if still thumbing */ + return; + + w->scrollbar.top = top > 1.0 ? 1.0 : top >= 0.0 ? top : w->scrollbar.top; + + w->scrollbar.shown = shown > 1.0 ? 1.0 : shown >= 0.0 ? + shown : w->scrollbar.shown; + PaintThumb(w); +} diff --git a/src/Simple.c b/src/Simple.c new file mode 100644 index 0000000..be5597b --- /dev/null +++ b/src/Simple.c @@ -0,0 +1,499 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include "Private.h" +#ifndef OLDXAW +#include +#endif + +/* + * Class Methods + */ +static Bool ChangeSensitive(Widget); +static void XawSimpleClassInitialize(void); +static void XawSimpleClassPartInitialize(WidgetClass); +#ifndef OLDXAW +static void XawSimpleInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawSimpleDestroy(Widget); +static void XawSimpleExpose(Widget, XEvent*, Region); +#endif +static void XawSimpleRealize(Widget, Mask*, XSetWindowAttributes*); +static Boolean XawSimpleSetValues(Widget, Widget, Widget, ArgList, Cardinal*); + +/* + * Prototypes + */ +static void ConvertCursor(Widget); + +/* + * Initialization + */ +#ifndef OLDXAW +static XtActionsRec actions[] = { + {"set-values", XawSetValuesAction}, + {"get-values", XawGetValuesAction}, + {"declare", XawDeclareAction}, + {"call-proc", XawCallProcAction}, +}; +#endif + +#define offset(field) XtOffsetOf(SimpleRec, simple.field) +static XtResource resources[] = { + { + XtNcursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(cursor), + XtRImmediate, + (XtPointer)None + }, + { + XtNinsensitiveBorder, + XtCInsensitive, + XtRPixmap, + sizeof(Pixmap), + offset(insensitive_border), + XtRImmediate, + NULL + }, + { + XtNpointerColor, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(pointer_fg), + XtRString, + XtDefaultForeground + }, + { + XtNpointerColorBackground, + XtCBackground, + XtRPixel, + sizeof(Pixel), + offset(pointer_bg), + XtRString, + XtDefaultBackground + }, + { + XtNcursorName, + XtCCursor, + XtRString, + sizeof(String), + offset(cursor_name), + XtRString, + NULL + }, + { + XtNinternational, + XtCInternational, + XtRBoolean, + sizeof(Boolean), + offset(international), + XtRImmediate, + (XtPointer)False + }, +#ifndef OLDXAW + { + XawNdisplayList, + XawCDisplayList, + XawRDisplayList, + sizeof(XawDisplayList*), + offset(display_list), + XtRImmediate, + NULL + }, + { + XtNtip, + XtCTip, + XtRString, + sizeof(String), + offset(tip), + XtRImmediate, + NULL + }, +#endif +#undef offset +}; + +SimpleClassRec simpleClassRec = { + /* core */ + { + (WidgetClass)&widgetClassRec, /* superclass */ + "Simple", /* class_name */ + sizeof(SimpleRec), /* widget_size */ + XawSimpleClassInitialize, /* class_initialize */ + XawSimpleClassPartInitialize, /* class_part_initialize */ + False, /* class_inited */ +#ifndef OLDXAW + XawSimpleInitialize, /* initialize */ +#else + NULL, /* initialize */ +#endif + NULL, /* initialize_hook */ + XawSimpleRealize, /* realize */ +#ifndef OLDXAW + actions, /* actions */ + XtNumber(actions), /* num_actions */ +#else + NULL, /* actions */ + 0, /* num_actions */ +#endif + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ +#ifndef OLDXAW + XawSimpleDestroy, /* destroy */ +#else + NULL, /* destroy */ +#endif + NULL, /* resize */ +#ifndef OLDXAW + XawSimpleExpose, /* expose */ +#else + NULL, /* expose */ +#endif + XawSimpleSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + ChangeSensitive, /* change_sensitive */ + }, +}; + +WidgetClass simpleWidgetClass = (WidgetClass)&simpleClassRec; + +static void +XawSimpleClassInitialize(void) +{ + static XtConvertArgRec convertArg[] = { + { + XtWidgetBaseOffset, + (XtPointer)XtOffsetOf(WidgetRec, core.screen), + sizeof(Screen *) + }, + { + XtResourceString, + (XtPointer)XtNpointerColor, + sizeof(Pixel) + }, + { + XtResourceString, + (XtPointer)XtNpointerColorBackground, + sizeof(Pixel) + }, + { + XtWidgetBaseOffset, + (XtPointer)XtOffsetOf(WidgetRec, core.colormap), + sizeof(Colormap) + }, + }; + + XawInitializeWidgetSet(); + XtSetTypeConverter(XtRString, XtRColorCursor, XmuCvtStringToColorCursor, + convertArg, XtNumber(convertArg), XtCacheByDisplay, NULL); +} + +static void +XawSimpleClassPartInitialize(WidgetClass cclass) +{ + SimpleWidgetClass c = (SimpleWidgetClass)cclass; + SimpleWidgetClass super = (SimpleWidgetClass)c->core_class.superclass; + + if (c->simple_class.change_sensitive == NULL) { + char buf[BUFSIZ]; + + snprintf(buf, sizeof(buf), + "%s Widget: The Simple Widget class method " + "'change_sensitive' is undefined.\n" + "A function must be defined or inherited.", + c->core_class.class_name); + XtWarning(buf); + c->simple_class.change_sensitive = ChangeSensitive; + } + + if (c->simple_class.change_sensitive == XtInheritChangeSensitive) + c->simple_class.change_sensitive = super->simple_class.change_sensitive; +} + +#ifndef OLDXAW +/*ARGSUSED*/ +static void +XawSimpleInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + SimpleWidget simple = (SimpleWidget)cnew; + + if (simple->simple.tip) + simple->simple.tip = XtNewString(simple->simple.tip); +} + +static void +XawSimpleDestroy(Widget w) +{ + SimpleWidget simple = (SimpleWidget)w; + + if (simple->simple.tip) + XtFree((XtPointer)simple->simple.tip); +} +#endif + +static void +XawSimpleRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) +{ +#ifndef OLDXAW + XawPixmap *pixmap; +#endif + Pixmap border_pixmap = CopyFromParent; + + if (!XtIsSensitive(w)) + { + /* change border to gray; have to remember the old one, + * so XtDestroyWidget deletes the proper one */ + if (((SimpleWidget)w)->simple.insensitive_border == None) + ((SimpleWidget)w)->simple.insensitive_border = + XmuCreateStippledPixmap(XtScreen(w), + w->core.border_pixel, + w->core.background_pixel, + w->core.depth); + border_pixmap = w->core.border_pixmap; + attributes->border_pixmap = + w->core.border_pixmap = ((SimpleWidget)w)->simple.insensitive_border; + + *valueMask |= CWBorderPixmap; + *valueMask &= ~CWBorderPixel; + } + + ConvertCursor(w); + + if ((attributes->cursor = ((SimpleWidget)w)->simple.cursor) != None) + *valueMask |= CWCursor; + + XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent, + *valueMask, attributes); + + if (!XtIsSensitive(w)) + w->core.border_pixmap = border_pixmap; + +#ifndef OLDXAW + if (w->core.background_pixmap > XtUnspecifiedPixmap) { + pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w), + w->core.colormap, w->core.depth); + if (pixmap && pixmap->mask) + XawReshapeWidget(w, pixmap); + } + + if (((SimpleWidget)w)->simple.tip) + XawTipEnable(w); +#endif +} + +/* + * Function: + * ConvertCursor + * + * Parameters: + * w - simple widget + * + * Description: + * Converts a name to a new cursor. + */ +static void +ConvertCursor(Widget w) +{ + SimpleWidget simple = (SimpleWidget) w; + XrmValue from, to; + Cursor cursor = None; + + if (simple->simple.cursor_name == NULL) + return; + + from.addr = (XPointer)simple->simple.cursor_name; + from.size = strlen((char *)from.addr) + 1; + + to.size = sizeof(Cursor); + to.addr = (XPointer)&cursor; + + if (XtConvertAndStore(w, XtRString, &from, XtRColorCursor, &to)) + simple->simple.cursor = cursor; + else + XtAppErrorMsg(XtWidgetToApplicationContext(w), + "convertFailed","ConvertCursor","XawError", + "Simple: ConvertCursor failed.", + NULL, NULL); +} + + +/*ARGSUSED*/ +static Boolean +XawSimpleSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + SimpleWidget s_old = (SimpleWidget)current; + SimpleWidget s_new = (SimpleWidget)cnew; + Bool new_cursor = False; + + /* this disables user changes after creation */ + s_new->simple.international = s_old->simple.international; + + if (XtIsSensitive(current) != XtIsSensitive(cnew)) + (*((SimpleWidgetClass)XtClass(cnew))->simple_class.change_sensitive) + (cnew); + + if (s_old->simple.cursor != s_new->simple.cursor) + new_cursor = True; + + /* + * We are not handling the string cursor_name correctly here + */ + + if (s_old->simple.pointer_fg != s_new->simple.pointer_fg || + s_old->simple.pointer_bg != s_new->simple.pointer_bg || + s_old->simple.cursor_name != s_new->simple.cursor_name) { + ConvertCursor(cnew); + new_cursor = True; + } + + if (new_cursor && XtIsRealized(cnew)) { + if (s_new->simple.cursor != None) + XDefineCursor(XtDisplay(cnew), XtWindow(cnew), s_new->simple.cursor); + else + XUndefineCursor(XtDisplay(cnew), XtWindow(cnew)); + } + +#ifndef OLDXAW + if (s_old->core.background_pixmap != s_new->core.background_pixmap) { + XawPixmap *opix, *npix; + + opix = XawPixmapFromXPixmap(s_old->core.background_pixmap, + XtScreen(s_old), s_old->core.colormap, + s_old->core.depth); + npix = XawPixmapFromXPixmap(s_new->core.background_pixmap, + XtScreen(s_new), s_new->core.colormap, + s_new->core.depth); + if ((npix && npix->mask) || (opix && opix->mask)) + XawReshapeWidget(cnew, npix); + } + + if (s_old->simple.tip != s_new->simple.tip) { + if (s_old->simple.tip) + XtFree((XtPointer)s_old->simple.tip); + if (s_new->simple.tip) + s_new->simple.tip = XtNewString(s_new->simple.tip); + } + + if (s_old->simple.tip && !s_new->simple.tip) + XawTipDisable(cnew); + else if (!s_old->simple.tip && s_new->simple.tip) + XawTipEnable(cnew); + + if (s_old->simple.display_list != s_new->simple.display_list) + return (True); +#endif /* OLDXAW */ + + return (False); +} + +#ifndef OLDXAW +static void +XawSimpleExpose(Widget w, XEvent *event, Region region) +{ + SimpleWidget xaw = (SimpleWidget)w; + + if (xaw->simple.display_list) + XawRunDisplayList(w, xaw->simple.display_list, event, region); +} +#endif + +static Bool +ChangeSensitive(Widget w) +{ + if (XtIsRealized(w)) { + if (XtIsSensitive(w)) + if (w->core.border_pixmap != XtUnspecifiedPixmap) + XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w), + w->core.border_pixmap); + else + XSetWindowBorder(XtDisplay(w), XtWindow(w), + w->core.border_pixel); + else { + if (((SimpleWidget)w)->simple.insensitive_border == None) + ((SimpleWidget)w)->simple.insensitive_border = + XmuCreateStippledPixmap(XtScreen(w), + w->core.border_pixel, + w->core.background_pixel, + w->core.depth); + XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w), + ((SimpleWidget)w)->simple.insensitive_border); + } + } + + return (False); +} diff --git a/src/SimpleMenu.c b/src/SimpleMenu.c new file mode 100644 index 0000000..8defdf7 --- /dev/null +++ b/src/SimpleMenu.c @@ -0,0 +1,1829 @@ +/* +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +/* + * SimpleMenu.c - Source code file for SimpleMenu widget. + * + * Date: April 3, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#define streq(a, b) (strcmp((a), (b)) == 0) + +#define ForAllChildren(smw, childP) \ +for ((childP) = (SmeObject *)(smw)->composite.children; \ + (childP) < (SmeObject *)((smw)->composite.children \ + + (smw)->composite.num_children); \ + (childP)++) + +#ifndef OLDXAW +#define SMW_UNMAPPING 0x01 +#define SMW_POPLEFT 0x02 +#endif + +/* + * Class Methods + */ +static void XawSimpleMenuChangeManaged(Widget); +static void XawSimpleMenuClassInitialize(void); +static void XawSimpleMenuClassPartInitialize(WidgetClass); +static XtGeometryResult XawSimpleMenuGeometryManager(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawSimpleMenuInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawSimpleMenuRealize(Widget, XtValueMask*, XSetWindowAttributes*); +static void XawSimpleMenuRedisplay(Widget, XEvent*, Region); +static void XawSimpleMenuResize(Widget); +static Boolean XawSimpleMenuSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static Boolean XawSimpleMenuSetValuesHook(Widget, ArgList, Cardinal*); +#ifndef OLDXAW +static void PopupSubMenu(SimpleMenuWidget); +static void PopdownSubMenu(SimpleMenuWidget); +static void PopupCB(Widget, XtPointer, XtPointer); +#endif + +/* + * Prototypes + */ +static void AddPositionAction(XtAppContext, XPointer); +static void CalculateNewSize(Widget, Dimension*, Dimension*); +static void ChangeCursorOnGrab(Widget, XtPointer, XtPointer); +static void CreateLabel(Widget); +static SmeObject DoGetEventEntry(Widget, int, int); +static Widget FindMenu(Widget, String); +static SmeObject GetEventEntry(Widget, XEvent*); +static void Layout(Widget, Dimension*, Dimension*); +static void MakeResizeRequest(Widget); +static void MakeSetValuesRequest(Widget, unsigned int, unsigned int); +static void MoveMenu(Widget, int, int); +static void PositionMenu(Widget, XPoint*); + +/* + * Actions + */ +static void Highlight(Widget, XEvent*, String*, Cardinal*); +static void Notify(Widget, XEvent*, String*, Cardinal*); +#ifndef OLDXAW +static void Popdown(Widget, XEvent*, String*, Cardinal*); +#endif +static void PositionMenuAction(Widget, XEvent*, String*, Cardinal*); +static void Unhighlight(Widget, XEvent*, String*, Cardinal*); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(SimpleMenuRec, simple_menu.field) + +static XtResource resources[] = { + /* label */ + { + XtNlabel, + XtCLabel, + XtRString, + sizeof(String), + offset(label_string), + XtRString, + NULL + }, + { + XtNlabelClass, + XtCLabelClass, + XtRPointer, + sizeof(WidgetClass), + offset(label_class), + XtRImmediate, + NULL + }, + + /* layout */ + { + XtNrowHeight, + XtCRowHeight, + XtRDimension, + sizeof(Dimension), + offset(row_height), + XtRImmediate, + (XtPointer)0 + }, + { + XtNtopMargin, + XtCVerticalMargins, + XtRDimension, + sizeof(Dimension), + offset(top_margin), + XtRImmediate, + (XtPointer)0 + }, + { + XtNbottomMargin, + XtCVerticalMargins, + XtRDimension, + sizeof(Dimension), + offset(bottom_margin), + XtRImmediate, + (XtPointer)0 + }, +#ifndef OLDXAW + { + XtNleftMargin, + XtCHorizontalMargins, + XtRDimension, + sizeof(Dimension), + offset(left_margin), + XtRImmediate, + (XtPointer)0 + }, + { + XtNrightMargin, + XtCHorizontalMargins, + XtRDimension, + sizeof(Dimension), + offset(right_margin), + XtRImmediate, + (XtPointer)0 + }, +#endif + + /* misc */ + { + XtNallowShellResize, + XtCAllowShellResize, + XtRBoolean, + sizeof(Boolean), + XtOffsetOf(SimpleMenuRec, shell.allow_shell_resize), + XtRImmediate, + (XtPointer)True + }, + { + XtNcursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(cursor), + XtRImmediate, + (XtPointer)None + }, + { + XtNmenuOnScreen, + XtCMenuOnScreen, + XtRBoolean, + sizeof(Boolean), + offset(menu_on_screen), + XtRImmediate, + (XtPointer)True + }, + { + XtNpopupOnEntry, + XtCPopupOnEntry, + XtRWidget, + sizeof(Widget), + offset(popup_entry), + XtRWidget, + NULL + }, + { + XtNbackingStore, + XtCBackingStore, + XtRBackingStore, + sizeof(int), + offset(backing_store), + XtRImmediate, + (XtPointer)(Always + WhenMapped + NotUseful) + }, +#ifndef OLDXAW + { + XawNdisplayList, + XawCDisplayList, + XawRDisplayList, + sizeof(XawDisplayList*), + offset(display_list), + XtRImmediate, + NULL + }, +#endif +}; +#undef offset + +static char defaultTranslations[] = +":" "highlight()\n" +":" "unhighlight()\n" +":" "highlight()\n" +#ifndef OLDXAW +":" "popdown() notify() unhighlight()\n" +#else +":" "MenuPopdown() notify() unhighlight()\n" +#endif +; + +static XtActionsRec actionsList[] = +{ + {"notify", Notify}, + {"highlight", Highlight}, + {"unhighlight", Unhighlight}, +#ifndef OLDXAW + {"popdown", Popdown}, + {"set-values", XawSetValuesAction}, + {"get-values", XawGetValuesAction}, + {"declare", XawDeclareAction}, + {"call-proc", XawCallProcAction}, +#endif +}; + +static CompositeClassExtensionRec extension_rec = { + NULL, /* next_extension */ + NULLQUARK, /* record_type */ + XtCompositeExtensionVersion, /* version */ + sizeof(CompositeClassExtensionRec), /* record_size */ + True, /* accepts_objects */ +}; + +#define Superclass (&overrideShellClassRec) +SimpleMenuClassRec simpleMenuClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "SimpleMenu", /* class_name */ + sizeof(SimpleMenuRec), /* size */ + XawSimpleMenuClassInitialize, /* class_initialize */ + XawSimpleMenuClassPartInitialize, /* class_part_initialize */ + False, /* class_inited */ + XawSimpleMenuInitialize, /* initialize */ + NULL, /* initialize_hook */ + XawSimpleMenuRealize, /* realize */ + actionsList, /* actions */ + XtNumber(actionsList), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + XawSimpleMenuResize, /* resize */ + XawSimpleMenuRedisplay, /* expose */ + XawSimpleMenuSetValues, /* set_values */ + XawSimpleMenuSetValuesHook, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* intrinsics version */ + NULL, /* callback offsets */ + defaultTranslations, /* tm_table */ + NULL, /* query_geometry */ + NULL, /* display_accelerator */ + NULL, /* extension */ + }, + /* composite */ + { + XawSimpleMenuGeometryManager, /* geometry_manager */ + XawSimpleMenuChangeManaged, /* change_managed */ + XtInheritInsertChild, /* insert_child */ + XtInheritDeleteChild, /* delete_child */ + NULL, /* extension */ + }, + /* shell */ + { + NULL, /* extension */ + }, + /* override */ + { + NULL, /* extension */ + }, + /* simple_menu */ + { + NULL, /* extension */ + }, +}; + +WidgetClass simpleMenuWidgetClass = (WidgetClass)&simpleMenuClassRec; + +/* + * Implementation + */ +/* + * Function: + * XawSimpleMenuClassInitialize + * + * Description: + * Class Initialize routine, called only once. + */ +static void +XawSimpleMenuClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore, + NULL, 0); + XtSetTypeConverter(XtRBackingStore, XtRString, XmuCvtBackingStoreToString, + NULL, 0, XtCacheNone, NULL); + XmuAddInitializer(AddPositionAction, NULL); +} + +/* + * Function: + * XawSimpleMenuClassPartInitialize + * Arguments: wc - the widget class of the subclass. + * + * Description: + * Class Part Initialize routine, called for every subclass. Makes + * sure that the subclasses pick up the extension record. + */ +static void +XawSimpleMenuClassPartInitialize(WidgetClass wc) +{ + SimpleMenuWidgetClass smwc = (SimpleMenuWidgetClass)wc; + + /* + * Make sure that our subclass gets the extension rec too + */ + extension_rec.next_extension = smwc->composite_class.extension; + smwc->composite_class.extension = (XtPointer) &extension_rec; +} + +/* + * Function: + * XawSimpleMenuInitialize + * + * Parameters: + * request - widget requested by the argument list + * cnew - new widget with both resource and non resource values + * + * Description: + * Initializes the simple menu widget. + */ +/*ARGSUSED*/ +static void +XawSimpleMenuInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)cnew; + Dimension width, height; + + XmuCallInitializers(XtWidgetToApplicationContext(cnew)); + + if (smw->simple_menu.label_class == NULL) + smw->simple_menu.label_class = smeBSBObjectClass; + + smw->simple_menu.label = NULL; + smw->simple_menu.entry_set = NULL; + smw->simple_menu.recursive_set_values = False; +#ifndef OLDXAW + smw->simple_menu.sub_menu = NULL; + smw->simple_menu.state = 0; + + XtAddCallback(cnew, XtNpopupCallback, PopupCB, NULL); +#endif + + if (smw->simple_menu.label_string != NULL) + CreateLabel(cnew); + + width = height = 0; + CalculateNewSize(cnew, &width, &height); + + smw->simple_menu.menu_width = True; + + if (XtWidth(smw) == 0) { + smw->simple_menu.menu_width = False; + XtWidth(smw) = width; + } + + smw->simple_menu.menu_height = True; + + if (XtHeight(smw) == 0) { + smw->simple_menu.menu_height = False; + XtHeight(smw) = height; + } + + /* + * Add a popup_callback routine for changing the cursor + */ + XtAddCallback(cnew, XtNpopupCallback, ChangeCursorOnGrab, NULL); +} + +/* + * Function: + * XawSimpleMenuRedisplay + * + * Parameters: + * w - simple menu widget + * event - X event that caused this redisplay + * region - region the needs to be repainted + * + * Description: + * Redisplays the contents of the widget. + */ +/*ARGSUSED*/ +static void +XawSimpleMenuRedisplay(Widget w, XEvent *event, Region region) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + SmeObject *entry; + SmeObjectClass cclass; + + if (region == NULL) + XClearWindow(XtDisplay(w), XtWindow(w)); + +#ifndef OLDXAW + if (smw->simple_menu.display_list) + XawRunDisplayList(w, smw->simple_menu.display_list, event, region); +#endif + + /* + * Check and Paint each of the entries - including the label + */ + ForAllChildren(smw, entry) { + if (!XtIsManaged((Widget)*entry)) + continue; + + if (region != NULL) + switch(XRectInRegion(region, XtX(*entry),XtY(*entry), + XtWidth(*entry), XtHeight(*entry))) { + case RectangleIn: + case RectanglePart: + break; + default: + continue; + } + + cclass = (SmeObjectClass)(*entry)->object.widget_class; + + if (cclass->rect_class.expose != NULL) + (cclass->rect_class.expose)((Widget)*entry, NULL, NULL); + } +} + +/* + * Function: + * XawSimpleMenuRealize + * + * Parameters: + * w - simple menu widget + * mask - value mask for the window to create + * attrs - attributes for the window to create + * + * Description: + * Realizes the widget. + */ +static void +XawSimpleMenuRealize(Widget w, XtValueMask *mask, XSetWindowAttributes *attrs) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; +#ifndef OLDXAW + XawPixmap *pixmap; +#endif + + attrs->cursor = smw->simple_menu.cursor; + *mask |= CWCursor; + if (smw->simple_menu.backing_store == Always || + smw->simple_menu.backing_store == NotUseful || + smw->simple_menu.backing_store == WhenMapped) { + *mask |= CWBackingStore; + attrs->backing_store = smw->simple_menu.backing_store; + } + else + *mask &= ~CWBackingStore; + + (*Superclass->core_class.realize)(w, mask, attrs); + +#ifndef OLDXAW + if (w->core.background_pixmap > XtUnspecifiedPixmap) { + pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w), + w->core.colormap, w->core.depth); + if (pixmap && pixmap->mask) + XawReshapeWidget(w, pixmap); + } +#endif +} + +/* + * Function: + * XawSimpleMenuResize + * + * Parameters: + * w - simple menu widget + * + * Description: + * Handle the menu being resized. + */ +static void +XawSimpleMenuResize(Widget w) +{ + if (!XtIsRealized(w)) + return; + + Layout(w, NULL, NULL); + + XawSimpleMenuRedisplay(w, NULL, NULL); +} + +/* + * Function: + * XawSimpleMenuSetValues + * + * Parameters: + * current - current state of the widget + * request - what was requested + * cnew - what the widget will become + * + * Description: + * Relayout the menu when one of the resources is changed. + */ +/*ARGSUSED*/ +static Boolean +XawSimpleMenuSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + SimpleMenuWidget smw_old = (SimpleMenuWidget)current; + SimpleMenuWidget smw_new = (SimpleMenuWidget)cnew; + Boolean ret_val = False, layout = False; + + if (!XtIsRealized(current)) + return (False); + + if (!smw_new->simple_menu.recursive_set_values) { + if (XtWidth(smw_new) != XtWidth(smw_old)) { + smw_new->simple_menu.menu_width = XtWidth(smw_new) != 0; + layout = True; + } + if (XtHeight(smw_new) != XtHeight(smw_old)) { + smw_new->simple_menu.menu_height = XtHeight(smw_new) != 0; + layout = True; + } + } + + if (smw_old->simple_menu.cursor != smw_new->simple_menu.cursor) + XDefineCursor(XtDisplay(cnew), XtWindow(cnew), + smw_new->simple_menu.cursor); + + if (smw_old->simple_menu.label_string !=smw_new->simple_menu.label_string) { + if (smw_new->simple_menu.label_string == NULL) /* Destroy */ + XtDestroyWidget((Widget)smw_old->simple_menu.label); + else if (smw_old->simple_menu.label_string == NULL) /* Create */ + CreateLabel(cnew); + else { /* Change */ + Arg arglist[1]; + + XtSetArg(arglist[0], XtNlabel, smw_new->simple_menu.label_string); + XtSetValues((Widget)smw_new->simple_menu.label, arglist, ONE); + } + } + + if (smw_old->simple_menu.label_class != smw_new->simple_menu.label_class) + XtAppWarning(XtWidgetToApplicationContext(cnew), + "No Dynamic class change of the SimpleMenu Label."); + + if (smw_old->simple_menu.top_margin != smw_new->simple_menu.top_margin + || smw_old->simple_menu.bottom_margin + != smw_new->simple_menu.bottom_margin) { + layout = True; + ret_val = True; + } + +#ifndef OLDXAW + if (smw_old->core.background_pixmap != smw_new->core.background_pixmap) { + XawPixmap *opix, *npix; + + opix = XawPixmapFromXPixmap(smw_old->core.background_pixmap, + XtScreen(smw_old), smw_old->core.colormap, + smw_old->core.depth); + npix = XawPixmapFromXPixmap(smw_new->core.background_pixmap, + XtScreen(smw_new), smw_new->core.colormap, + smw_new->core.depth); + if ((npix && npix->mask) || (opix && opix->mask)) + XawReshapeWidget(cnew, npix); + } +#endif + + if (layout) + Layout(cnew, NULL, NULL); + + return (ret_val); +} + +/* + * Function: + * XawSimpleMenuSetValuesHook + * + * Parameters: + * w - menu widget + * arglist - argument list passed to XtSetValues + * num_args - number of args + * + * Description: + * To handle a special case, this is passed the actual arguments. + */ +static Boolean +XawSimpleMenuSetValuesHook(Widget w, ArgList arglist, Cardinal *num_args) +{ + Cardinal i; + Dimension width, height; + + width = XtWidth(w); + height = XtHeight(w); + + for (i = 0 ; i < *num_args ; i++) { + if (streq(arglist[i].name, XtNwidth)) + width = (Dimension)arglist[i].value; + if (streq(arglist[i].name, XtNheight)) + height = (Dimension) arglist[i].value; + } + + if (width != XtWidth(w) || height != XtHeight(w)) + MakeSetValuesRequest(w, width, height); + + return (False); +} + +/* + * Geometry Management routines + */ +/* + * Function: + * XawSimpleMenuGeometryManager + * + * Parameters: + * w - Menu Entry making the request + * request - requested new geometry + * reply - the allowed geometry. + * + * Description: + * This is the SimpleMenu Widget's Geometry Manager. + * + * Returns: + * XtGeometry{Yes, No, Almost} + */ +static XtGeometryResult +XawSimpleMenuGeometryManager(Widget w, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)XtParent(w); + SmeObject entry = (SmeObject)w; + XtGeometryMask mode = request->request_mode; + XtGeometryResult answer; + Dimension old_height, old_width; + + if (!(mode & CWWidth) && !(mode & CWHeight)) + return (XtGeometryNo); + + reply->width = request->width; + reply->height = request->height; + + old_width = XtWidth(entry); + old_height = XtHeight(entry); + + Layout(w, &reply->width, &reply->height); + + /* + * Since we are an override shell and have no parent there is no one to + * ask to see if this geom change is okay, so I am just going to assume + * we can do whatever we want. If you subclass be very careful with this + * assumption, it could bite you. + * + * Chris D. Peterson - Sept. 1989. + */ + if ((!(mode & CWWidth) || reply->width == request->width) + && (!(mode & CWHeight) || reply->height == request->height)) { + if (mode & XtCWQueryOnly) { /* Actually perform the layout */ + XtWidth(entry) = old_width; + XtHeight(entry) = old_height; + } + else + Layout((Widget)smw, NULL, NULL); + answer = XtGeometryDone; + } + else { + XtWidth(entry) = old_width; + XtHeight(entry) = old_height; + + if ((reply->width == request->width && !(mode & CWHeight)) + || (reply->height == request->height && !(mode & CWWidth)) + || (reply->width == request->width + && reply->height == request->height)) + answer = XtGeometryNo; + else { + answer = XtGeometryAlmost; + reply->request_mode = 0; + if (reply->width != request->width) + reply->request_mode |= CWWidth; + if (reply->height != request->height) + reply->request_mode |= CWHeight; + } + } + + return (answer); +} + +/* + * Function: + * XawSimpleMenuChangeManaged + * + * Parameters: + * w - simple menu widget + * + * Description: + * Called whenever a new child is managed. + */ +static void +XawSimpleMenuChangeManaged(Widget w) +{ + Layout(w, NULL, NULL); +} + +/* + * Global Action Routines + * + * These actions routines will be added to the application's + * global action list + */ +/* + * Function: + * PositionMenuAction + * + * Parameters: + * w - a widget (no the simple menu widget) + * event - the event that caused this action + * params - parameters passed to the routine. + * we expect the name of the menu here. + * num_params - "" + * + * Description: + * Positions the simple menu widget. + */ +/*ARGSUSED*/ +static void +PositionMenuAction(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + Widget menu; + XPoint loc; + + if (*num_params != 1) { + XtAppWarning(XtWidgetToApplicationContext(w), + "SimpleMenuWidget: position menu action expects " + "only one parameter which is the name of the menu."); + return; + } + + if ((menu = FindMenu(w, params[0])) == NULL) { + char error_buf[BUFSIZ]; + + snprintf(error_buf, sizeof(error_buf), + "SimpleMenuWidget: could not find menu named %s.", + params[0]); + XtAppWarning(XtWidgetToApplicationContext(w), error_buf); + return; + } + + switch (event->type) { + case ButtonPress: + case ButtonRelease: + loc.x = event->xbutton.x_root; + loc.y = event->xbutton.y_root; + PositionMenu(menu, &loc); + break; + case EnterNotify: + case LeaveNotify: + loc.x = event->xcrossing.x_root; + loc.y = event->xcrossing.y_root; + PositionMenu(menu, &loc); + break; + case MotionNotify: + loc.x = event->xmotion.x_root; + loc.y = event->xmotion.y_root; + PositionMenu(menu, &loc); + break; + default: + PositionMenu(menu, NULL); + break; + } +} + +/* + * Widget Action Routines + */ +/* + * Function: + * Unhighlight + * + * Parameters: + * w - simple menu widget + * event - event that caused this action + * params - not used + * num_params - "" + * + * Description: + * Unhighlights current entry. + */ +/*ARGSUSED*/ +static void +Unhighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + SmeObject entry = smw->simple_menu.entry_set; + + if (entry == NULL) + return; + +#ifndef OLDXAW + if (!smw->simple_menu.sub_menu) +#endif + { + SmeObjectClass cclass; + + smw->simple_menu.entry_set = NULL; + cclass = (SmeObjectClass)entry->object.widget_class; + (cclass->sme_class.unhighlight)((Widget)entry); + } +} + +/* + * Function: + * Highlight + * + * Parameters: + * w - simple menu widget + * event - event that caused this action + * params - not used + * num_params - "" + * + * Description: + * Highlights current entry. + */ +/*ARGSUSED*/ +static void +Highlight(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + SmeObject entry; + + if (!XtIsSensitive(w)) + return; + + entry = GetEventEntry(w, event); + + if (entry == smw->simple_menu.entry_set) + return; + +#ifndef OLDXAW + if (!smw->simple_menu.sub_menu) +#endif + Unhighlight(w, event, params, num_params); + + if (entry == NULL) + return; + + if (!XtIsSensitive((Widget)entry)) + return; + +#ifndef OLDXAW + if (smw->simple_menu.sub_menu) + PopdownSubMenu(smw); +#endif + + Unhighlight(w, event, params, num_params); + +#ifndef OLDXAW + if (!(smw->simple_menu.state & SMW_UNMAPPING)) +#endif + { + SmeObjectClass cclass; + + smw->simple_menu.entry_set = entry; + cclass = (SmeObjectClass)entry->object.widget_class; + + (cclass->sme_class.highlight)((Widget)entry); + +#ifndef OLDXAW + if (XtIsSubclass((Widget)entry, smeBSBObjectClass)) + PopupSubMenu(smw); +#endif + } +} + +/* + * Function: + * Notify + * + * Parameters: + * w - simple menu widget + * event - event that caused this action + * params - not used + * num_params - "" + * + * Description: + * Notify user of current entry. + */ +/*ARGSUSED*/ +static void +Notify(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + SmeObject entry; + SmeObjectClass cclass; + + /* may be a propagated event from a sub menu, need to check it */ + if (XtWindow(w) != event->xany.window) + return; + entry = GetEventEntry(w, event); + if (entry == NULL || !XtIsSensitive((Widget)entry)) + return; + + cclass = (SmeObjectClass) entry->object.widget_class; + (cclass->sme_class.notify)((Widget)entry); +} + +/* + * Public Functions + */ +/* + * Function: + * XawSimpleMenuAddGlobalActions + * + * Arguments: + * app_con - appcontext + * + * Description: + * Adds the global actions to the simple menu widget. + */ +void +XawSimpleMenuAddGlobalActions(XtAppContext app_con) +{ + XtInitializeWidgetClass(simpleMenuWidgetClass); + XmuCallInitializers(app_con); +} + +/* + * Function: + * XawSimpleMenuGetActiveEntry + * + * Parameters: + * w - smw widget + * + * Description: + * Gets the currently active (set) entry. + * + * Returns: + * The currently set entry or NULL if none is set + */ +Widget +XawSimpleMenuGetActiveEntry(Widget w) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + + return ((Widget)smw->simple_menu.entry_set); +} + +/* + * Function: + * XawSimpleMenuClearActiveEntry + * + * Parameters: + * w - smw widget + * + * Description: + * Unsets the currently active (set) entry. + */ +void +XawSimpleMenuClearActiveEntry(Widget w) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + + smw->simple_menu.entry_set = NULL; +} + +/* + * Private Functions + */ +/* + * Function: + * CreateLabel + * + * Parameters: + * w - smw widget + * + * Description: + * Creates the label object and makes sure it is the first child in + * in the list. + */ +static void +CreateLabel(Widget w) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + Widget *child, *next_child; + int i; + Arg args[2]; + + if (smw->simple_menu.label_string == NULL || + smw->simple_menu.label != NULL) { + XtAppWarning(XtWidgetToApplicationContext(w), + "Xaw Simple Menu Widget: label string is NULL or " + "label already exists, no label is being created."); + return; + } + + XtSetArg(args[0], XtNlabel, smw->simple_menu.label_string); + XtSetArg(args[1], XtNjustify, XtJustifyCenter); + smw->simple_menu.label = (SmeObject) + XtCreateManagedWidget("menuLabel", + smw->simple_menu.label_class, w, args, TWO); + + next_child = NULL; + for (child = smw->composite.children + smw->composite.num_children, + i = smw->composite.num_children; i > 0; i--, child--) { + if (next_child != NULL) + *next_child = *child; + next_child = child; + } + *child = (Widget)smw->simple_menu.label; +} + +/* + * Function: + * Layout + * + * Arguments: + * w - See below + * width_ret - returned width + * height_ret - returned height + * + * Note: + * if width == NULL || height == NULL then it assumes the you do not care + * about the return values, and just want a relayout. + * + * if this is not the case then it will set width_ret and height_ret + * to be width and height that the child would get if it were layed out + * at this time. + * + * "w" can be the simple menu widget or any of its object children. + */ +static void +Layout(Widget w, Dimension *width_ret, Dimension *height_ret) +{ + SmeObject current_entry; + SimpleMenuWidget smw; + Dimension width, height; + Boolean allow_change_size; + Widget kid; + Cardinal i, count, n; + int width_kid, height_kid, tmp_w, tmp_h; + short vadd, hadd, x_ins, y_ins; + Dimension *widths; + + height = 0; + + if (XtIsSubclass(w, simpleMenuWidgetClass)) { + smw = (SimpleMenuWidget)w; + current_entry = NULL; + } + else { + smw = (SimpleMenuWidget)XtParent(w); + current_entry = (SmeObject)w; + } + + allow_change_size = (!XtIsRealized((Widget)smw) + || smw->shell.allow_shell_resize); + + for (i = smw->simple_menu.label ? 1 : 0; + i < smw->composite.num_children; + i++) { + XtWidgetGeometry preferred; + + kid = smw->composite.children[i]; + if (!XtIsManaged(kid)) + continue; + if (smw->simple_menu.row_height != 0) + XtHeight(kid) = smw->simple_menu.row_height; + XtQueryGeometry(kid, NULL, &preferred); + if (preferred.request_mode & CWWidth) + XtWidth(kid) = preferred.width; + } + + if (smw->simple_menu.label + && XtIsManaged((Widget)smw->simple_menu.label)) { + XtWidgetGeometry preferred; + + kid = (Widget)smw->simple_menu.label; + XtQueryGeometry(kid, NULL, &preferred); + if (preferred.request_mode & CWWidth) + XtWidth(kid) = preferred.width; + if (preferred.request_mode & CWHeight) + XtHeight(kid) = preferred.height; + } + + /* reset */ + if (!smw->simple_menu.menu_width) + XtWidth(smw) = 0; + if (!smw->simple_menu.menu_height) + XtHeight(smw) = 0; + if (!XtWidth(smw) || !XtHeight(smw)) + MakeResizeRequest((Widget)smw); + + widths = (Dimension *)XtMalloc(sizeof(Dimension)); +#ifndef OLDXAW + hadd = smw->simple_menu.left_margin; +#else + hadd = 0; +#endif + vadd = smw->simple_menu.top_margin; + if (smw->simple_menu.label) + vadd += XtHeight(smw->simple_menu.label); + + count = 1; + width = tmp_w = tmp_h = n = 0; + height = vadd; + + for (i = smw->simple_menu.label ? 1 : 0; + i < smw->composite.num_children; + i++) { + kid = smw->composite.children[i]; + if (!XtIsManaged(kid)) + continue; + width_kid = XtWidth(kid); + height_kid = XtHeight(kid); + + if (n && (height + height_kid + smw->simple_menu.bottom_margin + > XtHeight(smw))) { + ++count; + widths = (Dimension *)XtRealloc((char *)widths, + sizeof(Dimension) * count); + widths[count - 1] = width_kid; + width += tmp_w; + tmp_w = width_kid; + height = height_kid + vadd; + } + else + height += height_kid; + if (height > tmp_h) + tmp_h = height; + if (width_kid > tmp_w) + widths[count - 1] = tmp_w = width_kid; + ++n; + } + + height = tmp_h + smw->simple_menu.bottom_margin; + width += tmp_w; + + if (smw->simple_menu.label && width < XtWidth(smw->simple_menu.label)) { + float inc; + + inc = (XtWidth(smw->simple_menu.label) - width) / (float)count; + width = XtWidth(smw->simple_menu.label); + for (n = 0; n < count; n++) + widths[n] += inc; + } + +#ifndef OLDXAW + width += hadd + smw->simple_menu.right_margin; +#endif + + x_ins = n = count = 0; + tmp_w = widths[0]; + tmp_h = vadd; + + for (i = smw->simple_menu.label ? 1 : 0; + i < smw->composite.num_children; + i++) { + kid = smw->composite.children[i]; + if (!XtIsManaged(kid)) + continue; + + height_kid = XtHeight(kid); + + if (n && (tmp_h + height_kid + smw->simple_menu.bottom_margin + > XtHeight(smw))) { + x_ins = tmp_w; + y_ins = vadd; + ++count; + tmp_w += widths[count]; + tmp_h = height_kid + vadd; + } + else { + y_ins = tmp_h; + tmp_h += height_kid; + } + ++n; + + XtX(kid) = x_ins + hadd; + XtY(kid) = y_ins; + XtWidth(kid) = widths[count]; + } + + XtFree((char *)widths); + + if (allow_change_size) + MakeSetValuesRequest((Widget) smw, width, height); + + if (smw->simple_menu.label) { + XtX(smw->simple_menu.label) = 0; + XtY(smw->simple_menu.label) = smw->simple_menu.top_margin; + XtWidth(smw->simple_menu.label) = XtWidth(smw) +#ifndef OLDXAW + - (smw->simple_menu.left_margin + smw->simple_menu.right_margin) +#endif + ; + } + if (current_entry) { + if (width_ret) + *width_ret = XtWidth(current_entry); + if (height_ret) + *height_ret = XtHeight(current_entry); + } +} + +/* + * Function: + * AddPositionAction + * + * Parameters: + * app_con - application context + * data - (not used) + * + * Description: + * Adds the XawPositionSimpleMenu action to the global + * action list for this appcon. + */ +/*ARGSUSED*/ +static void +AddPositionAction(XtAppContext app_con, XPointer data) +{ + static XtActionsRec pos_action[] = { + {"XawPositionSimpleMenu", PositionMenuAction}, + }; + + XtAppAddActions(app_con, pos_action, XtNumber(pos_action)); +} + +/* + * Function: + * FindMenu + * + * Parameters: + * widget - reference widget + * name - menu widget's name + * + * Description: + * Find the menu give a name and reference widget + * + * Returns: + * The menu widget or NULL. + */ +static Widget +FindMenu(Widget widget, String name) +{ + Widget w, menu; + + for (w = widget; w != NULL; w = XtParent(w)) + if ((menu = XtNameToWidget(w, name)) != NULL) + return (menu); + + return (NULL); +} + +/* + * Function: + * PositionMenu + * + * Parameters: + * w - simple menu widget + * location - pointer the the position or NULL + * + * Description: + * Places the menu + */ +static void +PositionMenu(Widget w, XPoint *location) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + SmeObject entry; + XPoint t_point; + + if (location == NULL) { + Window temp1, temp2; + int root_x, root_y, tempX, tempY; + unsigned int tempM; + + location = &t_point; + if (XQueryPointer(XtDisplay(w), XtWindow(w), &temp1, &temp2, + &root_x, &root_y, &tempX, &tempY, &tempM) == False) { + XtAppWarning(XtWidgetToApplicationContext(w), + "Xaw Simple Menu Widget: " + "Could not find location of mouse pointer"); + return; + } + location->x = (short) root_x; + location->y = (short) root_y; + } + + /* + * The width will not be correct unless it is realized + */ + XtRealizeWidget(w); + + location->x -= XtWidth(w) >> 1; + + if (smw->simple_menu.popup_entry == NULL) + entry = smw->simple_menu.label; + else + entry = smw->simple_menu.popup_entry; + + if (entry != NULL) + location->y -= XtY(entry) + (XtHeight(entry) >> 1); + + MoveMenu(w, location->x, location->y); +} + +/* + * Function: + * MoveMenu + * + * Parameters: + * w - simple menu widget + * x - current location of the widget + * y - "" + * + * Description: + * Actually moves the menu, may force it to + * to be fully visable if menu_on_screen is True. + */ +static void +MoveMenu(Widget w, int x, int y) +{ + Arg arglist[2]; + Cardinal num_args = 0; + SimpleMenuWidget smw = (SimpleMenuWidget)w; + + if (smw->simple_menu.menu_on_screen) { + int width = XtWidth(w) + (XtBorderWidth(w) << 1); + int height = XtHeight(w) + (XtBorderWidth(w) << 1); + + if (x >= 0) { + int scr_width = WidthOfScreen(XtScreen(w)); + + if (x + width > scr_width) + x = scr_width - width; + } + if (x < 0) + x = 0; + + if (y >= 0) { + int scr_height = HeightOfScreen(XtScreen(w)); + + if (y + height > scr_height) + y = scr_height - height; + } + if (y < 0) + y = 0; + } + + XtSetArg(arglist[num_args], XtNx, x); num_args++; + XtSetArg(arglist[num_args], XtNy, y); num_args++; + XtSetValues(w, arglist, num_args); +} + +/* + * Function: + * ChangeCursorOnGrab + * + * Parameters: + * w - menu widget + * temp1 - not used + * temp2 - "" + * + * Description: + * Changes the cursor on the active grab to the one + * specified in out resource list. + */ +/*ARGSUSED*/ +static void +ChangeCursorOnGrab(Widget w, XtPointer temp1, XtPointer temp2) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + + /* + * The event mask here is what is currently in the MIT implementation. + * There really needs to be a way to get the value of the mask out + * of the toolkit (CDP 5/26/89). + */ + XChangeActivePointerGrab(XtDisplay(w), ButtonPressMask | ButtonReleaseMask, + smw->simple_menu.cursor, + XtLastTimestampProcessed(XtDisplay(w))); +} + +/* + * Function: + * MakeSetValuesRequest + * + * Parameters: + * w - simple menu widget + * width - size requested + * height - "" + */ +static void +MakeSetValuesRequest(Widget w, unsigned int width, unsigned int height) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + Arg arglist[2]; + Cardinal num_args = 0; + + if (!smw->simple_menu.recursive_set_values) { + if (XtWidth(smw) != width || XtHeight(smw) != height) { + smw->simple_menu.recursive_set_values = True; + XtSetArg(arglist[num_args], XtNwidth, width); num_args++; + XtSetArg(arglist[num_args], XtNheight, height); num_args++; + XtSetValues(w, arglist, num_args); + } + else if (XtIsRealized((Widget)smw)) + XawSimpleMenuRedisplay((Widget)smw, NULL, NULL); + } + smw->simple_menu.recursive_set_values = False; +} + +static SmeObject +DoGetEventEntry(Widget w, int x_loc, int y_loc) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + SmeObject *entry; + + ForAllChildren(smw, entry) { + if (!XtIsManaged((Widget)*entry)) + continue; + + if (x_loc > XtX(*entry) + && x_loc <= XtX(*entry) + XtWidth(*entry) + && y_loc > XtY(*entry) + && y_loc <= XtY(*entry) + XtHeight(*entry)) { + if (*entry == smw->simple_menu.label) + return (NULL); /* cannot select the label */ + else + return (*entry); + } + } + + return (NULL); +} + +/* + * Function: + * GetEventEntry + * + * Parameters: + * w - simple menu widget + * event - X event + * + * Description: + * Gets an entry given an event that has X and Y coords. + * + * Returns: + * The entry that this point is in + */ +static SmeObject +GetEventEntry(Widget w, XEvent *event) +{ + int x_loc, y_loc, x_root; + SimpleMenuWidget smw = (SimpleMenuWidget)w; + SmeObject entry; + int warp, move; + + switch (event->type) { + case MotionNotify: + x_loc = event->xmotion.x; + y_loc = event->xmotion.y; + x_root = event->xmotion.x_root; + break; + case EnterNotify: + case LeaveNotify: + x_loc = event->xcrossing.x; + y_loc = event->xcrossing.y; + x_root = event->xcrossing.x_root; + break; + case ButtonPress: + case ButtonRelease: + x_loc = event->xbutton.x; + y_loc = event->xbutton.y; + x_root = event->xbutton.x_root; + break; + default: + XtAppError(XtWidgetToApplicationContext(w), + "Unknown event type in GetEventEntry()."); + return (NULL); + } + + if (x_loc < 0 || x_loc >= XtWidth(smw) || + y_loc < 0 || y_loc >= XtHeight(smw)) + return (NULL); + + /* Move the menu if it's outside the screen, does not check + * smw->simple_menu.menu_on_screen because menus is bigger than screen + */ + if (x_root == WidthOfScreen(XtScreen(w)) - 1 && + XtX(w) + XtWidth(w) + (XtBorderWidth(w)) > x_root) { + warp = -8; + if (smw->simple_menu.entry_set) { + entry = DoGetEventEntry(w, + XtX(smw->simple_menu.entry_set) + + XtWidth(smw->simple_menu.entry_set) + 1, + y_loc); + Unhighlight(w, event, NULL, NULL); + if (entry) { + warp = -(int)XtWidth(entry) >> 1; + move = x_loc - XtWidth(entry) - XtX(entry) + XtBorderWidth(w); + } + else { + warp = 0; + move = WidthOfScreen(XtScreen(w)) - + (XtX(w) + XtWidth(w) + (XtBorderWidth(w) << 1)); + } + } + else { + warp = 0; + move = WidthOfScreen(XtScreen(w)) - + (XtX(w) + XtWidth(w) + (XtBorderWidth(w) << 1)); + } + } + else if (x_root == 0 && XtX(w) < 0) { + warp = 8; + if (smw->simple_menu.entry_set) { + entry = DoGetEventEntry(w, XtX(smw->simple_menu.entry_set) - 1, + y_loc); + Unhighlight(w, event, NULL, NULL); + if (entry) { + warp = XtWidth(entry) >> 1; + move = x_loc - XtX(entry); + } + else + move = x_loc + XtBorderWidth(w); + } + else + move = x_loc + XtBorderWidth(w); + } + else + move = warp = 0; + + if (move) + XtMoveWidget(w, XtX(w) + move, XtY(w)); + if (warp) + XWarpPointer(XtDisplay(w), None, None, 0, 0, 0, 0, warp, 0); + + return (DoGetEventEntry(w, x_loc, y_loc)); +} + +static void +CalculateNewSize(Widget w, Dimension *width_return, Dimension *height_return) +{ + SimpleMenuWidget xaw = (SimpleMenuWidget)w; + Widget kid; + Cardinal i; + int width_kid, height_kid; + int width, height, tmp_w, tmp_h, max_dim; + short vadd, hadd; + int n, columns, test_h, num_children = 0; + Boolean try_layout = False; + +#ifndef OLDXAW + hadd = xaw->simple_menu.left_margin + xaw->simple_menu.right_margin; +#else + hadd = 0; +#endif + vadd = xaw->simple_menu.top_margin + xaw->simple_menu.bottom_margin; + if (xaw->simple_menu.label) + vadd += XtHeight(xaw->simple_menu.label); + + if (*height_return) + max_dim = *height_return; + else if (!XtHeight(w)) { + max_dim = HeightOfScreen(XtScreen(w)); + try_layout = True; + } + else + max_dim = XtHeight(w); + max_dim -= vadd; + + width = height = tmp_w = tmp_h = n = test_h = 0; + columns = 1; + for (i = xaw->simple_menu.label ? 1 : 0; + i < xaw->composite.num_children; + i++) { + kid = xaw->composite.children[i]; + if (!XtIsManaged(kid)) + continue; + ++num_children; + width_kid = XtWidth(kid); + height_kid = XtHeight(kid); + + if (try_layout) { + if (!test_h) + test_h = height_kid; + else if (test_h != height_kid) + try_layout = False; + } + + if (n && (height + height_kid > max_dim)) { + ++columns; + width += tmp_w; + tmp_w = width_kid; + height = height_kid; + } + else + height += height_kid; + if (height > tmp_h) + tmp_h = height; + if (width_kid > tmp_w) + tmp_w = width_kid; + ++n; + } + + height = tmp_h + vadd; + width += tmp_w + hadd; + + if (xaw->simple_menu.label) + width = XawMax(width, XtWidth(xaw->simple_menu.label) + hadd); + + *width_return = width; + *height_return = height; + + if (try_layout && columns > 1 && num_children > 2) { + int space; + + height = test_h * (xaw->simple_menu.label ? + num_children - 1 : + num_children); + + max_dim -= max_dim % test_h; + space = max_dim - (height % max_dim); + if (space >= test_h * columns) { + height = max_dim - space / columns; + if (height % test_h) + height += test_h - (height % test_h); + *height_return = height + vadd; + CalculateNewSize(w, width_return, height_return); + } + } +} + +static void +MakeResizeRequest(Widget w) +{ + int tries; + Dimension width, height; + + width = XtWidth(w); + height = XtHeight(w); + + for (tries = 0; tries < 100; tries++) { + CalculateNewSize(w, &width, &height); + if (width == XtWidth(w) && height == XtHeight(w)) + break; + if (XtMakeResizeRequest(w, width, height, &width, &height) == + XtGeometryNo) + break; + } +} + +#ifndef OLDXAW +static void +Popdown(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + + while (XtParent(w) && + XtIsSubclass(XtParent(w), simpleMenuWidgetClass)) { + if (((SimpleMenuWidget)XtParent(w))->simple_menu.sub_menu == (Widget)w) { + w = XtParent(w); + smw = (SimpleMenuWidget)w; + smw->simple_menu.entry_set = NULL; + } + else + break; + } + + smw->simple_menu.state |= SMW_UNMAPPING; + if (smw->simple_menu.sub_menu) + PopdownSubMenu(smw); + XtCallActionProc(w, "XtMenuPopdown", event, params, *num_params); +} + +static void +PopupSubMenu(SimpleMenuWidget smw) +{ + Arg args[2]; + Cardinal num_args; + Widget menu; + SmeBSBObject entry = (SmeBSBObject)smw->simple_menu.entry_set; + Position menu_x, menu_y; + Bool popleft; + + if (entry->sme_bsb.menu_name == NULL) + return; + + if ((menu = FindMenu((Widget)smw, entry->sme_bsb.menu_name)) == NULL) + return; + + smw->simple_menu.sub_menu = menu; + + if (!XtIsRealized(menu)) + XtRealizeWidget(menu); + + popleft = (smw->simple_menu.state & SMW_POPLEFT) != 0; + + if (popleft) + XtTranslateCoords((Widget)smw, -(int)XtWidth(menu), + XtY(entry) - XtBorderWidth(menu), &menu_x, &menu_y); + else + XtTranslateCoords((Widget)smw, XtWidth(smw), XtY(entry) + - XtBorderWidth(menu), &menu_x, &menu_y); + + if (!popleft && menu_x >= 0) { + int scr_width = WidthOfScreen(XtScreen(menu)); + + if (menu_x + XtWidth(menu) > scr_width) { + menu_x -= XtWidth(menu) + XtWidth(smw); + popleft = True; + } + } + else if (popleft && menu_x < 0) { + menu_x = 0; + popleft = False; + } + if (menu_y >= 0) { + int scr_height = HeightOfScreen(XtScreen(menu)); + + if (menu_y + XtHeight(menu) > scr_height) + menu_y = scr_height - XtHeight(menu) - XtBorderWidth(menu); + } + if (menu_y < 0) + menu_y = 0; + + num_args = 0; + XtSetArg(args[num_args], XtNx, menu_x); num_args++; + XtSetArg(args[num_args], XtNy, menu_y); num_args++; + XtSetValues(menu, args, num_args); + + if (popleft) + ((SimpleMenuWidget)menu)->simple_menu.state |= SMW_POPLEFT; + else + ((SimpleMenuWidget)menu)->simple_menu.state &= ~SMW_POPLEFT; + + XtPopup(menu, XtGrabNone); +} + +static void +PopdownSubMenu(SimpleMenuWidget smw) +{ + SimpleMenuWidget menu = (SimpleMenuWidget)smw->simple_menu.sub_menu; + + if (!menu) + return; + + menu->simple_menu.state |= SMW_UNMAPPING; + PopdownSubMenu(menu); + + XtPopdown((Widget)menu); + + smw->simple_menu.sub_menu = NULL; +} + +/*ARGSUSED*/ +static void +PopupCB(Widget w, XtPointer client_data, XtPointer call_data) +{ + SimpleMenuWidget smw = (SimpleMenuWidget)w; + + smw->simple_menu.state &= ~(SMW_UNMAPPING | SMW_POPLEFT); +} +#endif /* OLDXAW */ diff --git a/src/Sme.c b/src/Sme.c new file mode 100644 index 0000000..24d4fed --- /dev/null +++ b/src/Sme.c @@ -0,0 +1,269 @@ +/* +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +/* + * Date: September 26, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include "Private.h" + +/* + * Class Methods + */ +static void Highlight(Widget); +static void Notify(Widget); +static void Unhighlight(Widget); +static void XawSmeClassPartInitialize(WidgetClass); +static void XawSmeInitialize(Widget, Widget, ArgList, Cardinal*); +static XtGeometryResult XawSmeQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(SmeRec, sme.field) +static XtResource resources[] = { + { + XtNcallback, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + offset(callbacks), + XtRCallback, + NULL + }, + { + XtNinternational, + XtCInternational, + XtRBoolean, + sizeof(Boolean), + offset(international), + XtRImmediate, + (XtPointer)False + }, +}; +#undef offset + +#define Superclass (&rectObjClassRec) +SmeClassRec smeClassRec = { + /* rectangle */ + { + (WidgetClass)Superclass, /* superclass */ + "Sme", /* class_name */ + sizeof(SmeRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + XawSmeClassPartInitialize, /* class_part_initialize */ + False, /* class_initialized */ + XawSmeInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* compress_motion */ + False, /* compress_exposure */ + False, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + NULL, /* resize */ + NULL, /* expose */ + NULL, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* intrinsics_version */ + NULL, /* callback offsets */ + NULL, /* tm_table */ + XawSmeQueryGeometry, /* query_geometry */ + NULL, /* display_accelerator */ + NULL, /* extension */ + }, + /* sme */ + { + Highlight, /* highlight */ + Unhighlight, /* unhighlight */ + Notify, /* notify */ + NULL, /* extension */ + } +}; + +WidgetClass smeObjectClass = (WidgetClass)&smeClassRec; + +/* + * Implementation + */ +/* + * Function: + * XawSmeClassPartInitialize + * + * Parameters: + * cclass - widget classs of this widget + * + * Description: + * Handles inheritance of class functions. + */ +static void +XawSmeClassPartInitialize(WidgetClass cclass) +{ + SmeObjectClass m_ent, superC; + + m_ent = (SmeObjectClass)cclass; + superC = (SmeObjectClass)m_ent->rect_class.superclass; + + if (m_ent->sme_class.highlight == XtInheritHighlight) + m_ent->sme_class.highlight = superC->sme_class.highlight; + + if (m_ent->sme_class.unhighlight == XtInheritUnhighlight) + m_ent->sme_class.unhighlight = superC->sme_class.unhighlight; + + if (m_ent->sme_class.notify == XtInheritNotify) + m_ent->sme_class.notify = superC->sme_class.notify; +} + +/* + * Function: + * XawSmeInitialize + * + * Parameters: + * request - widget requested by the argument list + * cnew - new widget with both resource and non resource values + * + * Description: + * Initializes the simple menu widget entry + */ +/*ARGSUSED*/ +static void +XawSmeInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + SmeObject entry = (SmeObject)cnew; + + entry->rectangle.border_width = 0; +} + +/* + * Function: + * Highlight + * + * Parameters: + * w - menu entry + * + * Description: + * Default highlight proceedure for menu entries. + */ +/*ARGSUSED*/ +static void +Highlight(Widget w) +{ +} + +/* + * Function: + * Unhighlight + * + * Parameters: + * w - menu entry + * + * Description: + * Default unhighlight proceedure for menu entries. + */ +/*ARGSUSED*/ +static void +Unhighlight(Widget w) +{ +} + +/* + * Function: + * Notify + * + * Parameters: + * w - menu entry + * + * Description: + * Calls the callback proceedures for this entry. + */ +static void +Notify(Widget w) +{ + XtCallCallbacks(w, XtNcallback, NULL); +} + +/* + * Function: + * QueryGeometry + * + * Parameeters: + * w - menu entry object + * itended - intended and return geometry info + * return_val - + * + * Description: + * Returns the preferred geometry for this widget. + * + * Returns: + * Geometry Result + * + * Note: + * See the Intrinsics manual for details on what this function is for. + */ +static XtGeometryResult +XawSmeQueryGeometry(Widget w, XtWidgetGeometry *intended, + XtWidgetGeometry *return_val) +{ + SmeObject entry = (SmeObject)w; + Dimension width; + XtGeometryResult ret_val = XtGeometryYes; + XtGeometryMask mode = intended->request_mode; + + width = 1; + + if (((mode & CWWidth) && intended->width != width) || !(mode & CWWidth)) { + return_val->request_mode |= CWWidth; + return_val->width = width; + mode = return_val->request_mode; + + if ((mode & CWWidth) && width == XtWidth(entry)) + return (XtGeometryNo); + return (XtGeometryAlmost); + } + + return (ret_val); +} diff --git a/src/SmeBSB.c b/src/SmeBSB.c new file mode 100644 index 0000000..52a789a --- /dev/null +++ b/src/SmeBSB.c @@ -0,0 +1,769 @@ +/* +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +/* + * SmeBSB.c - Source code file for BSB Menu Entry object. + * + * Date: September 26, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#define ONE_HUNDRED 100 + +/* + * Class Methods + */ +static void FlipColors(Widget); +static void XawSmeBSBClassInitialize(void); +static void XawSmeBSBInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawSmeBSBDestroy(Widget); +static XtGeometryResult XawSmeBSBQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawSmeBSBRedisplay(Widget, XEvent*, Region); +static Boolean XawSmeBSBSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * Prototypes + */ +static void CreateGCs(Widget); +static void GetBitmapInfo(Widget, Bool); +static void GetDefaultSize(Widget, Dimension*, Dimension*); +static void DestroyGCs(Widget); +static void DrawBitmaps(Widget, GC); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(SmeBSBRec, sme_bsb.field) +static XtResource resources[] = { + { + XtNlabel, + XtCLabel, + XtRString, + sizeof(String), + offset(label), + XtRString, + NULL + }, + { + XtNvertSpace, + XtCVertSpace, + XtRInt, + sizeof(int), + offset(vert_space), + XtRImmediate, + (XtPointer)25 + }, + { + XtNleftBitmap, + XtCLeftBitmap, + XtRBitmap, + sizeof(Pixmap), + offset(left_bitmap), + XtRImmediate, + (XtPointer)None + }, + { + XtNjustify, + XtCJustify, + XtRJustify, + sizeof(XtJustify), + offset(justify), + XtRImmediate, + (XtPointer)XtJustifyLeft + }, + { + XtNrightBitmap, + XtCRightBitmap, + XtRBitmap, + sizeof(Pixmap), + offset(right_bitmap), + XtRImmediate, + (XtPointer)None + }, + { + XtNleftMargin, + XtCHorizontalMargins, + XtRDimension, + sizeof(Dimension), + offset(left_margin), + XtRImmediate, + (XtPointer)4 + }, + { + XtNrightMargin, + XtCHorizontalMargins, + XtRDimension, + sizeof(Dimension), + offset(right_margin), + XtRImmediate, + (XtPointer)4 + }, + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(foreground), + XtRString, + XtDefaultForeground + }, + { + XtNfont, + XtCFont, + XtRFontStruct, + sizeof(XFontStruct*), + offset(font), + XtRString, + XtDefaultFont + }, + { + XtNfontSet, + XtCFontSet, + XtRFontSet, + sizeof(XFontSet), + offset(fontset), + XtRString, + XtDefaultFontSet + }, +#ifndef OLDXAW + { + XtNmenuName, + XtCMenuName, + XtRString, + sizeof(String), + offset(menu_name), + XtRImmediate, + (XtPointer)NULL + }, +#endif +}; +#undef offset + +#define superclass (&smeClassRec) +SmeBSBClassRec smeBSBClassRec = { + /* rectangle */ + { + (WidgetClass)superclass, /* superclass */ + "SmeBSB", /* class_name */ + sizeof(SmeBSBRec), /* size */ + XawSmeBSBClassInitialize, /* class_init */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawSmeBSBInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* compress_motion */ + False, /* compress_exposure */ + False, /* compress_enterleave */ + False, /* visible_interest */ + XawSmeBSBDestroy, /* destroy */ + NULL, /* resize */ + XawSmeBSBRedisplay, /* expose */ + XawSmeBSBSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* intrinsics version */ + NULL, /* callback offsets */ + NULL, /* tm_table */ + XawSmeBSBQueryGeometry, /* query_geometry */ + NULL, /* display_accelerator */ + NULL, /* extension */ + }, + /* sme */ + { + FlipColors, /* highlight */ + FlipColors, /* unhighlight */ + XtInheritNotify, /* notify */ + NULL, /* extension */ + }, + /* sme_bsb */ + { + NULL, /* extension */ + }, +}; +WidgetClass smeBSBObjectClass = (WidgetClass)&smeBSBClassRec; + +/* + * Function: + * XawSmeBSBClassInitialize + * + * Description: + * Initializes the SmeBSBObject. + */ +static void +XawSmeBSBClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtAddConverter(XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0); + XtSetTypeConverter(XtRJustify, XtRString, XmuCvtJustifyToString, + NULL, 0, XtCacheNone, NULL); +} + +/* + * Function: + * XawSmeBSBInitialize + * + * Parameters: + * request - widget requested by the argument list + * cnew - new widget with both resource and non resource values + * + * Description: + * Initializes the simple menu widget entry. + */ +/*ARGSUSED*/ +static void +XawSmeBSBInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + SmeBSBObject entry = (SmeBSBObject)cnew; + + if (!entry->sme_bsb.font) XtError("Aborting: no font found\n"); + + if (entry->sme_bsb.label == NULL) + entry->sme_bsb.label = XtName(cnew); + else + entry->sme_bsb.label = XtNewString(entry->sme_bsb.label); + + GetDefaultSize(cnew, &entry->rectangle.width, &entry->rectangle.height); + CreateGCs(cnew); + + entry->sme_bsb.left_bitmap_width = entry->sme_bsb.left_bitmap_height = 0; + entry->sme_bsb.right_bitmap_width = entry->sme_bsb.right_bitmap_height = 0; + + GetBitmapInfo(cnew, True); /* Left Bitmap Info */ + GetBitmapInfo(cnew, False); /* Right Bitmap Info */ +} + +/* + * Function: + * XawSmeBSBDestroy + * + * Parameters: + * w - simple menu widget entry + */ +static void +XawSmeBSBDestroy(Widget w) +{ + SmeBSBObject entry = (SmeBSBObject)w; + + DestroyGCs(w); + if (entry->sme_bsb.label != XtName(w)) + XtFree(entry->sme_bsb.label); +} + +/* + * Function: + * XawSmeBSBRedisplay + * + * Parameters: + * w - simple menu widget entry + * event - X event that caused this redisplay + * region - region the needs to be repainted + * + * Description: + * Redisplays the contents of the widget. + */ +/* ARGSUSED */ +static void +XawSmeBSBRedisplay(Widget w, XEvent *event, Region region) +{ + GC gc; + SmeBSBObject entry = (SmeBSBObject)w; + int font_ascent, font_descent, y_loc; + int fontset_ascent, fontset_descent; + XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset); + + font_ascent = font_descent = fontset_ascent = fontset_descent = 0; + entry->sme_bsb.set_values_area_cleared = False; + + if (entry->sme.international == True) { + fontset_ascent = XawAbs(ext->max_ink_extent.y); + fontset_descent = ext->max_ink_extent.height - fontset_ascent; + } + else { + font_ascent = entry->sme_bsb.font->max_bounds.ascent; + font_descent = entry->sme_bsb.font->max_bounds.descent; + } + y_loc = XtY(entry); + + if (XtIsSensitive(w) && XtIsSensitive(XtParent(w))) { + if (w == XawSimpleMenuGetActiveEntry(XtParent(w))) { + XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), + entry->sme_bsb.norm_gc, XtX(w), y_loc, + XtWidth(entry), XtHeight(entry)); + gc = entry->sme_bsb.rev_gc; + } + else + gc = entry->sme_bsb.norm_gc; + } + else + gc = entry->sme_bsb.norm_gray_gc; + + if (entry->sme_bsb.label != NULL) { + int x_loc = entry->sme_bsb.left_margin; + int len = strlen(entry->sme_bsb.label); + char *label = entry->sme_bsb.label; + int width, t_width; + + switch(entry->sme_bsb.justify) { + case XtJustifyCenter: + if (entry->sme.international == True) { + t_width = XmbTextEscapement(entry->sme_bsb.fontset,label, + len); + width = XtWidth(entry) - (entry->sme_bsb.left_margin + + entry->sme_bsb.right_margin); + } + else { + t_width = XTextWidth(entry->sme_bsb.font, label, len); + width = XtWidth(entry) - (entry->sme_bsb.left_margin + + entry->sme_bsb.right_margin); + } + x_loc += (width - t_width) >> 1; + break; + case XtJustifyRight: + if (entry->sme.international == True) { + t_width = XmbTextEscapement(entry->sme_bsb.fontset,label, + len); + x_loc = XtWidth(entry) - (entry->sme_bsb.right_margin + + t_width); + } + else { + t_width = XTextWidth(entry->sme_bsb.font, label, len); + x_loc = XtWidth(entry) - (entry->sme_bsb.right_margin + + t_width); + } + break; + case XtJustifyLeft: + /*FALLTHROUGH*/ + default: + break; + } + + /* this will center the text in the gadget top-to-bottom */ + if (entry->sme.international == True) { + y_loc += ((XtHeight(entry) - + (fontset_ascent + fontset_descent)) >> 1) + + fontset_ascent; + + XmbDrawString(XtDisplayOfObject(w), XtWindowOfObject(w), + entry->sme_bsb.fontset, gc, + XtX(w) + x_loc, y_loc, label, len); + } + else { + y_loc += ((XtHeight(entry) - + (font_ascent + font_descent)) >> 1) + font_ascent; + + XDrawString(XtDisplayOfObject(w), XtWindowOfObject(w), gc, + XtX(w) + x_loc, y_loc, label, len); + } + } + + DrawBitmaps(w, gc); +} + + +/* + * Function: + * XawSmeBSBSetValues + * + * Parameters: + * current - current state of the widget + * request - what was requested + * cnew - what the widget will become + * + * Description: + * Relayout the menu when one of the resources is changed. + */ + +/*ARGSUSED*/ +static Boolean +XawSmeBSBSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + SmeBSBObject entry = (SmeBSBObject)cnew; + SmeBSBObject old_entry = (SmeBSBObject)current; + Boolean ret_val = False; + + if (old_entry->sme_bsb.label != entry->sme_bsb.label) { + if (old_entry->sme_bsb.label != XtName(cnew)) + XtFree((char *)old_entry->sme_bsb.label); + + if (entry->sme_bsb.label != XtName(cnew)) + entry->sme_bsb.label = XtNewString(entry->sme_bsb.label); + + ret_val = True; + } + + if (entry->rectangle.sensitive != old_entry->rectangle.sensitive) + ret_val = True; + + if (entry->sme_bsb.left_bitmap != old_entry->sme_bsb.left_bitmap) { + GetBitmapInfo(cnew, True); + ret_val = True; + } + + if (entry->sme_bsb.right_bitmap != old_entry->sme_bsb.right_bitmap) { + GetBitmapInfo(cnew, False); + ret_val = True; + } + + if ((old_entry->sme_bsb.font != entry->sme_bsb.font + && old_entry->sme.international == False) + || old_entry->sme_bsb.foreground != entry->sme_bsb.foreground) { + DestroyGCs(current); + CreateGCs(cnew); + ret_val = True; + } + + if (old_entry->sme_bsb.fontset != entry->sme_bsb.fontset && + old_entry->sme.international == True) + /* DONT changes the GCs, because the fontset is not in them */ + ret_val = True; + + if (ret_val) { + Dimension width, height; + + GetDefaultSize(cnew, &width, &height); + entry->sme_bsb.set_values_area_cleared = True; + XtMakeResizeRequest(cnew, width, height, NULL, NULL); + } + + return (ret_val); +} + +/* + * Function: + * XawSmeBSBQueryGeometry + * + * Parameters: + * w - menu entry object + * itended - intended and return geometry info + * return_val - "" + * + * Returns: + * Geometry Result + * + * Description: + * Returns the preferred geometry for this widget. + * See the Intrinsics manual for details on what this function is for. + */ +static XtGeometryResult +XawSmeBSBQueryGeometry(Widget w, XtWidgetGeometry *intended, + XtWidgetGeometry *return_val) +{ + SmeBSBObject entry = (SmeBSBObject)w; + Dimension width, height; + XtGeometryResult ret_val = XtGeometryYes; + XtGeometryMask mode = intended->request_mode; + + GetDefaultSize(w, &width, &height); + + if (((mode & CWWidth) && intended->width != width) || !(mode & CWWidth)) { + return_val->request_mode |= CWWidth; + return_val->width = width; + ret_val = XtGeometryAlmost; + } + + if (((mode & CWHeight) && intended->height != height) || !(mode & CWHeight)) { + return_val->request_mode |= CWHeight; + return_val->height = height; + ret_val = XtGeometryAlmost; + } + + if (ret_val == XtGeometryAlmost) { + mode = return_val->request_mode; + if (((mode & CWWidth) && width == XtWidth(entry)) && + ((mode & CWHeight) && height == XtHeight(entry))) + return (XtGeometryNo); + } + + return (ret_val); +} + +/* + * Function: + * FlipColors + * + * Parameters: + * w - bsb menu entry widget + * + * Description: + * Invert the colors of the current entry. + */ +static void +FlipColors(Widget w) +{ + SmeBSBObject entry = (SmeBSBObject)w; + + if (entry->sme_bsb.set_values_area_cleared) + return; + + XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), + entry->sme_bsb.invert_gc, + XtX(w), XtY(entry), XtWidth(entry), XtHeight(entry)); +} + +/* + * Function: + * GetDefaultSize + * + * Parameters: + * w - menu entry widget. + * width - default width (return) + * height - default height (return) + * + * Description: + * Calculates the Default (preferred) size of this menu entry. + */ +static void +GetDefaultSize(Widget w, Dimension *width, Dimension *height) +{ + SmeBSBObject entry = (SmeBSBObject)w; + + if (entry->sme.international == True) { + XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset); + + if (entry->sme_bsb.label == NULL) + *width = 0; + else + *width = XmbTextEscapement(entry->sme_bsb.fontset, + entry->sme_bsb.label, + strlen(entry->sme_bsb.label)); + *width += entry->sme_bsb.left_margin + entry->sme_bsb.right_margin; + *height = ext->max_ink_extent.height; + *height = ((int)*height * (ONE_HUNDRED + + entry->sme_bsb.vert_space)) / ONE_HUNDRED; + } + else { + if (entry->sme_bsb.label == NULL) + *width = 0; + else + *width = XTextWidth(entry->sme_bsb.font, entry->sme_bsb.label, + strlen(entry->sme_bsb.label)); + + *width += entry->sme_bsb.left_margin + entry->sme_bsb.right_margin; + + *height = entry->sme_bsb.font->max_bounds.ascent + + entry->sme_bsb.font->max_bounds.descent; + + *height = ((int)*height * (ONE_HUNDRED + + entry->sme_bsb.vert_space)) / ONE_HUNDRED; + } +} + +/* + * Function: + * DrawBitmaps + * + * Parameters: + * w - simple menu widget entry + * gc - graphics context to use for drawing + * + * Description: + * Draws left and right bitmaps. + */ +static void +DrawBitmaps(Widget w, GC gc) +{ + int x_loc, y_loc; + SmeBSBObject entry = (SmeBSBObject)w; + + if (entry->sme_bsb.left_bitmap == None && + entry->sme_bsb.right_bitmap == None) + return; + + /* + * Draw Left Bitmap + */ + if (entry->sme_bsb.left_bitmap != None) { + x_loc = ((entry->sme_bsb.left_margin - + entry->sme_bsb.left_bitmap_width) >> 1) + XtX(w); + + y_loc = XtY(entry) + ((XtHeight(entry) - + entry->sme_bsb.left_bitmap_height) >> 1); + + XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.left_bitmap, + XtWindowOfObject(w), gc, 0, 0, + entry->sme_bsb.left_bitmap_width, + entry->sme_bsb.left_bitmap_height, x_loc, y_loc, 1); + } + + /* + * Draw Right Bitmap + */ + if (entry->sme_bsb.right_bitmap != None) { + x_loc = XtWidth(entry) - ((entry->sme_bsb.right_margin + + entry->sme_bsb.right_bitmap_width) >> 1) + + XtX(w); + y_loc = XtY(entry) + ((XtHeight(entry) - + entry->sme_bsb.right_bitmap_height) >> 1); + + XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.right_bitmap, + XtWindowOfObject(w), gc, 0, 0, + entry->sme_bsb.right_bitmap_width, + entry->sme_bsb.right_bitmap_height, x_loc, y_loc, 1); + } +} + +/* + * Function: + * GetBitmapInfo + * + * Parameters: + * w - bsb menu entry object + * is_left - True: if we are testing left bitmap + * False: if we are testing the right bitmap + * + * Description: + * Gets the bitmap information from either of the bitmaps. + */ +static void +GetBitmapInfo(Widget w, Bool is_left) +{ + SmeBSBObject entry = (SmeBSBObject)w; + unsigned int depth, bw; + Window root; + int x, y; + unsigned int width, height; + + if (is_left) { + if (entry->sme_bsb.left_bitmap != None && + XGetGeometry(XtDisplayOfObject(w), + entry->sme_bsb.left_bitmap, &root, + &x, &y, &width, &height, &bw, &depth)) { + entry->sme_bsb.left_bitmap_width = width; + entry->sme_bsb.left_bitmap_height = height; + } + } + else if (entry->sme_bsb.right_bitmap != None && + XGetGeometry(XtDisplayOfObject(w), + entry->sme_bsb.right_bitmap, &root, + &x, &y, &width, &height, &bw, &depth)) { + entry->sme_bsb.right_bitmap_width = width; + entry->sme_bsb.right_bitmap_height = height; + } +} + +/* + * Function: + * CreateGCs + * + * Parameters: + * w - simple menu widget entry + * + * Description: + * Creates all gc's for the simple menu widget. + */ +static void +CreateGCs(Widget w) +{ + SmeBSBObject entry = (SmeBSBObject)w; + XGCValues values; + XtGCMask mask, mask_i18n; + + values.foreground = XtParent(w)->core.background_pixel; + values.background = entry->sme_bsb.foreground; + values.font = entry->sme_bsb.font->fid; + values.graphics_exposures = False; + mask = GCForeground | GCBackground | GCGraphicsExposures | GCFont; + mask_i18n = GCForeground | GCBackground | GCGraphicsExposures; + if (entry->sme.international == True) + entry->sme_bsb.rev_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0); + else + entry->sme_bsb.rev_gc = XtGetGC(w, mask, &values); + + values.foreground = entry->sme_bsb.foreground; + values.background = XtParent(w)->core.background_pixel; + if (entry->sme.international == True) + entry->sme_bsb.norm_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0); + else + entry->sme_bsb.norm_gc = XtGetGC(w, mask, &values); + + values.fill_style = FillTiled; + values.tile = XmuCreateStippledPixmap(XtScreenOfObject(w), + entry->sme_bsb.foreground, + XtParent(w)->core.background_pixel, + XtParent(w)->core.depth); + values.graphics_exposures = False; + mask |= GCTile | GCFillStyle; + mask_i18n |= GCTile | GCFillStyle; + if (entry->sme.international == True) + entry->sme_bsb.norm_gray_gc = XtAllocateGC(w, 0, mask_i18n, &values, + GCFont, 0); + else + entry->sme_bsb.norm_gray_gc = XtGetGC(w, mask, &values); + + values.foreground ^= values.background; + values.background = 0; + values.function = GXxor; + mask = GCForeground | GCBackground | GCGraphicsExposures | GCFunction; + entry->sme_bsb.invert_gc = XtGetGC(w, mask, &values); +} + +/* + * Function: + * DestroyGCs + * + * Parameters: + * w - simple menu widget entry + * + * Description: + * Removes all gc's for the simple menu widget. + */ +static void +DestroyGCs(Widget w) +{ + SmeBSBObject entry = (SmeBSBObject)w; + + XtReleaseGC(w, entry->sme_bsb.norm_gc); + XtReleaseGC(w, entry->sme_bsb.norm_gray_gc); + XtReleaseGC(w, entry->sme_bsb.rev_gc); + XtReleaseGC(w, entry->sme_bsb.invert_gc); +} diff --git a/src/SmeLine.c b/src/SmeLine.c new file mode 100644 index 0000000..8011342 --- /dev/null +++ b/src/SmeLine.c @@ -0,0 +1,264 @@ +/* +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Chris D. Peterson, MIT X Consortium + */ + +/* + * Sme.c - Source code for the generic menu entry + * + * Date: September 26, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include "Private.h" + +/* + * Class Methods + */ +static void XawSmeLineDestroy(Widget); +static void XawSmeLineInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawSmeLineRedisplay(Widget, XEvent*, Region); +static Boolean XawSmeLineSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * Prototypes + */ +static void CreateGC(Widget); +static void DestroyGC(Widget); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(SmeLineRec, sme_line.field) +static XtResource resources[] = { + { + XtNlineWidth, + XtCLineWidth, + XtRDimension, + sizeof(Dimension), + offset(line_width), + XtRImmediate, + (XtPointer)1 + }, + { + XtNstipple, + XtCStipple, + XtRBitmap, + sizeof(Pixmap), + offset(stipple), + XtRImmediate, + (XtPointer)XtUnspecifiedPixmap + }, + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(foreground), + XtRString, + XtDefaultForeground + }, +}; +#undef offset + +#define Superclass (&smeClassRec) +SmeLineClassRec smeLineClassRec = { + /* rectangle */ + { + (WidgetClass)Superclass, /* superclass */ + "SmeLine", /* class_name */ + sizeof(SmeLineRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class inited */ + XawSmeLineInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* compress_motion */ + False, /* compress_exposure */ + False, /* compress_enterleave */ + False, /* visible_interest */ + XawSmeLineDestroy, /* destroy */ + NULL, /* resize */ + XawSmeLineRedisplay, /* expose */ + XawSmeLineSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* intrinsics version */ + NULL, /* callback offsets */ + NULL, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + NULL, /* display_accelerator */ + NULL, /* extension */ + }, + /* sme */ + { + XtInheritHighlight, /* highlight */ + XtInheritUnhighlight, /* unhighlight */ + XtInheritNotify, /* notify */ + NULL, /* extension */ + }, + /* sme_line */ + { + NULL, /* extension */ + } +}; + +WidgetClass smeLineObjectClass = (WidgetClass)&smeLineClassRec; + +/* + * Implementation + */ +/*ARGSUSED*/ +static void +XawSmeLineInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + SmeLineObject entry = (SmeLineObject)cnew; + + if (XtHeight(entry) == 0) + XtHeight(entry) = entry->sme_line.line_width; + + CreateGC(cnew); +} + +/* + * Function: + * CreateGC + * + * Parameters: + * w - Line entry widget + * + * Description: + * Creates the GC for the line entry widget. + * + * Note: + * We can only share the GC if there is no stipple, because + * we need to change the stipple origin when drawing + */ +static void +CreateGC(Widget w) +{ + SmeLineObject entry = (SmeLineObject)w; + XGCValues values; + XtGCMask mask = GCForeground | GCGraphicsExposures | GCLineWidth; + + values.foreground = entry->sme_line.foreground; + values.graphics_exposures = False; + values.line_width = entry->sme_line.line_width; + + if (entry->sme_line.stipple != XtUnspecifiedPixmap) { + values.stipple = entry->sme_line.stipple; + values.fill_style = FillStippled; + mask |= GCStipple | GCFillStyle; + + entry->sme_line.gc = XCreateGC(XtDisplayOfObject(w), + RootWindowOfScreen(XtScreenOfObject(w)), + mask, &values); + } + else + entry->sme_line.gc = XtGetGC(w, mask, &values); +} + +static void +XawSmeLineDestroy(Widget w) +{ + DestroyGC(w); +} + +static void +DestroyGC(Widget w) +{ + SmeLineObject entry = (SmeLineObject)w; + + if (entry->sme_line.stipple != XtUnspecifiedPixmap) + XFreeGC(XtDisplayOfObject(w), entry->sme_line.gc); + else + XtReleaseGC(w, entry->sme_line.gc); +} + +/*ARGSUSED*/ +static void +XawSmeLineRedisplay(Widget w, XEvent *event, Region region) +{ + SmeLineObject entry = (SmeLineObject)w; + int y = XtY(w) + (((int)XtHeight(w) - entry->sme_line.line_width) >> 1); + + if (entry->sme_line.stipple != XtUnspecifiedPixmap) + XSetTSOrigin(XtDisplayOfObject(w), entry->sme_line.gc, 0, y); + + XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), + entry->sme_line.gc, XtX(w), y, + XtWidth(w), entry->sme_line.line_width); +} + +/* + * Function: + * XawSmeLineSetValues + * + * Parameters: + * current - current state of the widget + * request - what was requested + * cnew - what the widget will become + * + * Description: + * Relayout the menu when one of the resources is changed. + */ +/*ARGSUSED*/ +static Boolean +XawSmeLineSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + SmeLineObject entry = (SmeLineObject)cnew; + SmeLineObject old_entry = (SmeLineObject)current; + + if (entry->sme_line.line_width != old_entry->sme_line.line_width && + entry->sme_line.stipple != old_entry->sme_line.stipple) { + DestroyGC(current); + CreateGC(cnew); + return (True); + } + + return (False); +} diff --git a/src/StripChart.c b/src/StripChart.c new file mode 100644 index 0000000..fa7357c --- /dev/null +++ b/src/StripChart.c @@ -0,0 +1,576 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#define MS_PER_SEC 1000 + +/* + * Class Methods + */ +static void XawStripChartInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawStripChartDestroy(Widget); +static void XawStripChartRedisplay(Widget, XEvent*, Region); +static void XawStripChartResize(Widget); +static Boolean XawStripChartSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * Prototypes + */ +static void CreateGC(StripChartWidget, unsigned int); +static void DestroyGC(StripChartWidget, unsigned int); +static void draw_it(XtPointer, XtIntervalId*); +static void MoveChart(StripChartWidget, Bool); +static int repaint_window(StripChartWidget, int, int); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(StripChartRec, field) +static XtResource resources[] = { + { + XtNwidth, + XtCWidth, + XtRDimension, + sizeof(Dimension), + offset(core.width), + XtRImmediate, + (XtPointer) + 120 + }, + { + XtNheight, + XtCHeight, + XtRDimension, + sizeof(Dimension), + offset(core.height), + XtRImmediate, + (XtPointer)120 + }, + { + XtNupdate, + XtCInterval, + XtRInt, + sizeof(int), + offset(strip_chart.update), + XtRImmediate, + (XtPointer)10 + }, + { + XtNminScale, + XtCScale, + XtRInt, + sizeof(int), + offset(strip_chart.min_scale), + XtRImmediate, + (XtPointer)1 + }, + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(strip_chart.fgpixel), + XtRString, + XtDefaultForeground + }, + { + XtNhighlight, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(strip_chart.hipixel), + XtRString, + XtDefaultForeground + }, + { + XtNgetValue, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + offset(strip_chart.get_value), + XtRImmediate, + NULL + }, + { + XtNjumpScroll, + XtCJumpScroll, + XtRInt, + sizeof(int), + offset(strip_chart.jump_val), + XtRImmediate, + (XtPointer)DEFAULT_JUMP + }, +}; +#undef offset + +StripChartClassRec stripChartClassRec = { + /* core */ + { + (WidgetClass)&simpleClassRec, /* superclass */ + "StripChart", /* class_name */ + sizeof(StripChartRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawStripChartInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + XtExposeCompressMultiple /* compress_exposure */ + | XtExposeGraphicsExposeMerged, + True, /* compress_enterleave */ + False, /* visible_interest */ + XawStripChartDestroy, /* destroy */ + XawStripChartResize, /* resize */ + XawStripChartRedisplay, /* expose */ + XawStripChartSetValues, /* set_values */ + NULL, /* set_values_hook */ + NULL, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + } +}; + +WidgetClass stripChartWidgetClass = (WidgetClass)&stripChartClassRec; + +/* + * Implementation + */ +/* + * Function: + * CreateGC + * + * Parameters: + * w - strip chart widget + * which - GC's to create + * + * Description: + * Creates the GC's + */ +static void +CreateGC(StripChartWidget w, unsigned int which) +{ + XGCValues myXGCV; + + if (which & FOREGROUND) { + myXGCV.foreground = w->strip_chart.fgpixel; + w->strip_chart.fgGC = XtGetGC((Widget)w, GCForeground, &myXGCV); + } + + if (which & HIGHLIGHT) { + myXGCV.foreground = w->strip_chart.hipixel; + w->strip_chart.hiGC = XtGetGC((Widget)w, GCForeground, &myXGCV); + } +} + +/* + * Function: + * DestroyGC + * + * Arguments: + * w - strip chart widget + * which - which GC's to destroy + * + * Description: + * Destroys the GC's + */ +static void +DestroyGC(StripChartWidget w, unsigned int which) +{ + if (which & FOREGROUND) + XtReleaseGC((Widget)w, w->strip_chart.fgGC); + + if (which & HIGHLIGHT) + XtReleaseGC((Widget)w, w->strip_chart.hiGC); +} + +/*ARGSUSED*/ +static void +XawStripChartInitialize(Widget greq, Widget gnew, + ArgList args, Cardinal *num_args) +{ + StripChartWidget w = (StripChartWidget)gnew; + + if (w->strip_chart.update > 0) + w->strip_chart.interval_id = + XtAppAddTimeOut(XtWidgetToApplicationContext(gnew), + w->strip_chart.update * MS_PER_SEC, + draw_it, (XtPointer)gnew); + CreateGC(w, ALL_GCS); + + w->strip_chart.scale = w->strip_chart.min_scale; + w->strip_chart.interval = 0; + w->strip_chart.max_value = 0.0; + w->strip_chart.points = NULL; + XawStripChartResize(gnew); +} + +static void +XawStripChartDestroy(Widget gw) +{ + StripChartWidget w = (StripChartWidget)gw; + + if (w->strip_chart.update > 0) + XtRemoveTimeOut(w->strip_chart.interval_id); + if (w->strip_chart.points) + XtFree((char *)w->strip_chart.points); + DestroyGC(w, ALL_GCS); +} + +/* + * NOTE: This function really needs to recieve graphics exposure + * events, but since this is not easily supported until R4 I am + * going to hold off until then. + */ +/*ARGSUSED*/ +static void +XawStripChartRedisplay(Widget w, XEvent *event, Region region) +{ + if (event->type == GraphicsExpose) + (void)repaint_window((StripChartWidget)w, event->xgraphicsexpose.x, + event->xgraphicsexpose.width); + else + (void)repaint_window((StripChartWidget)w, event->xexpose.x, + event->xexpose.width); +} + +/*ARGSUSED*/ +static void +draw_it(XtPointer client_data, XtIntervalId *id) +{ + StripChartWidget w = (StripChartWidget)client_data; + double value; + + if (w->strip_chart.update > 0) + w->strip_chart.interval_id = + XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)w), + w->strip_chart.update * MS_PER_SEC,draw_it, + client_data); + + if (w->strip_chart.interval >= XtWidth(w)) + MoveChart((StripChartWidget)w, True); + + /* Get the value, stash the point and draw corresponding line */ + if (w->strip_chart.get_value == NULL) + return; + + XtCallCallbacks((Widget)w, XtNgetValue, (XtPointer)&value); + + /* + * Keep w->strip_chart.max_value up to date, and if this data + * point is off the graph, change the scale to make it fit + */ + if (value > w->strip_chart.max_value) { + w->strip_chart.max_value = value; + if (XtIsRealized((Widget)w) && + w->strip_chart.max_value > w->strip_chart.scale) { + XClearWindow(XtDisplay(w), XtWindow(w)); + w->strip_chart.interval = repaint_window(w, 0, XtWidth(w)); + } + } + + w->strip_chart.valuedata[w->strip_chart.interval] = value; + if (XtIsRealized((Widget)w)) { + int y = (int)(XtHeight(w) - XtHeight(w) * value + / w->strip_chart.scale); + + XFillRectangle(XtDisplay(w), XtWindow(w), w->strip_chart.fgGC, + w->strip_chart.interval, y, + 1, XtHeight(w) - y); + + /* + * Fill in the graph lines we just painted over + */ + if (w->strip_chart.points != NULL) { + w->strip_chart.points[0].x = w->strip_chart.interval; + XDrawPoints(XtDisplay(w), XtWindow(w), w->strip_chart.hiGC, + w->strip_chart.points, w->strip_chart.scale - 1, + CoordModePrevious); + } + + XFlush(XtDisplay(w)); /* Flush output buffers */ + } + w->strip_chart.interval++; /* Next point */ +} + +/* Blts data according to current size, then redraws the stripChart window + * Next represents the number of valid points in data. Returns the (possibly) + * adjusted value of next. If next is 0, this routine draws an empty window + * (scale - 1 lines for graph). If next is less than the current window width, + * the returned value is identical to the initial value of next and data is + * unchanged. Otherwise keeps half a window's worth of data. If data is + * changed, then w->strip_chart.max_value is updated to reflect the + * largest data point + */ +static int +repaint_window(StripChartWidget w, int left, int width) +{ + int i, j; + int next = w->strip_chart.interval; + int scale = w->strip_chart.scale; + int scalewidth = 0; + + /* Compute the minimum scale required to graph the data, but don't go + lower than min_scale */ + if (w->strip_chart.interval != 0 || scale <= w->strip_chart.max_value) + scale = w->strip_chart.max_value + 1; + if (scale < w->strip_chart.min_scale) + scale = w->strip_chart.min_scale; + + if (scale != w->strip_chart.scale) { + w->strip_chart.scale = scale; + left = 0; + width = next; + scalewidth = XtWidth(w); + + XawStripChartResize((Widget)w); + + if (XtIsRealized((Widget)w)) + XClearWindow(XtDisplay(w), XtWindow(w)); + } + + if (XtIsRealized((Widget)w)) { + Display *dpy = XtDisplay(w); + Window win = XtWindow(w); + + width += left - 1; + if (!scalewidth) + scalewidth = width; + + if (next < ++width) + width = next; + + /* Draw data point lines */ + for (i = left; i < width; i++) { + int y = XtHeight(w) - (XtHeight(w) * w->strip_chart.valuedata[i]) + / w->strip_chart.scale; + + XFillRectangle(dpy, win, w->strip_chart.fgGC, + i, y, 1, XtHeight(w) - y); + } + + /* Draw graph reference lines */ + for (i = 1; i < w->strip_chart.scale; i++) { + j = i * ((int)XtHeight(w) / w->strip_chart.scale); + XDrawLine(dpy, win, w->strip_chart.hiGC, left, j, scalewidth, j); + } + } + return (next); +} + +/* + * Function: + * MoveChart + * + * Parameters: + * w - chart widget + * blit - blit the bits? + * + * Description: + * Moves the chart over when it would run off the end. + */ +static void +MoveChart(StripChartWidget w, Bool blit) +{ + double old_max; + int left, i, j; + int next = w->strip_chart.interval; + + if (!XtIsRealized((Widget)w)) + return; + + if (w->strip_chart.jump_val < 0) + w->strip_chart.jump_val = DEFAULT_JUMP; + if (w->strip_chart.jump_val == DEFAULT_JUMP) + j = XtWidth(w) >> 1; + else { + j = (int)XtWidth(w) - w->strip_chart.jump_val; + if (j < 0) + j = 0; + } + + (void)memmove((char *)w->strip_chart.valuedata, + (char *)(w->strip_chart.valuedata + next - j), + j * sizeof(double)); + next = w->strip_chart.interval = j; + + /* + * Since we just lost some data, recompute the + * w->strip_chart.max_value + */ + old_max = w->strip_chart.max_value; + w->strip_chart.max_value = 0.0; + for (i = 0; i < next; i++) { + if (w->strip_chart.valuedata[i] > w->strip_chart.max_value) + w->strip_chart.max_value = w->strip_chart.valuedata[i]; + } + + if (!blit) + return; + + if (old_max != w->strip_chart.max_value) { + XClearWindow(XtDisplay(w), XtWindow(w)); + repaint_window(w, 0, XtWidth(w)); + return; + } + + XCopyArea(XtDisplay((Widget)w), XtWindow((Widget)w), XtWindow((Widget)w), + w->strip_chart.hiGC, (int)XtWidth(w) - j, 0, j, XtHeight(w), 0, 0); + + XClearArea(XtDisplay((Widget)w), XtWindow((Widget)w), + j, 0, XtWidth(w) - j, XtHeight(w), False); + + /* Draw graph reference lines */ + left = j; + for (i = 1; i < w->strip_chart.scale; i++) { + j = i * (XtHeight(w) / w->strip_chart.scale); + XDrawLine(XtDisplay((Widget)w), XtWindow((Widget)w), + w->strip_chart.hiGC, left, j, XtWidth(w), j); + } +} + +/*ARGSUSED*/ +static Boolean +XawStripChartSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + StripChartWidget old = (StripChartWidget)current; + StripChartWidget w = (StripChartWidget)cnew; + Bool ret_val = False; + unsigned int new_gc = NO_GCS; + + if (w->strip_chart.update != old->strip_chart.update) { + if (old->strip_chart.update > 0) + XtRemoveTimeOut(old->strip_chart.interval_id); + if (w->strip_chart.update > 0) + w->strip_chart.interval_id = + XtAppAddTimeOut(XtWidgetToApplicationContext(cnew), + w->strip_chart.update * MS_PER_SEC, + draw_it, (XtPointer)w); + } + + if (w->strip_chart.min_scale > w->strip_chart.max_value + 1) + ret_val = True; + + if (w->strip_chart.fgpixel != old->strip_chart.fgpixel) { + new_gc |= FOREGROUND; + ret_val = True; + } + + if (w->strip_chart.hipixel != old->strip_chart.hipixel) { + new_gc |= HIGHLIGHT; + ret_val = True; + } + + DestroyGC(old, new_gc); + CreateGC(w, new_gc); + + return (ret_val); +} + +/* + * Function: + * XawStripChartResize + * + * Parameters: + * w - StripChart widget + * + * Description: + * Sets up the polypoint that will be used to draw in the graph lines. + */ +static void +XawStripChartResize(Widget widget) +{ + StripChartWidget w = (StripChartWidget)widget; + XPoint *points; + Cardinal size; + int i; + + if (w->strip_chart.scale <= 1) { + XtFree((char *)w->strip_chart.points); + w->strip_chart.points = NULL; + return; + } + + size = sizeof(XPoint) * (w->strip_chart.scale - 1); + + points = (XPoint *)XtRealloc((XtPointer)w->strip_chart.points, size); + w->strip_chart.points = points; + + /* Draw graph reference lines into clip mask */ + + for (i = 1; i < w->strip_chart.scale; i++) { + points[i - 1].x = 0; + points[i - 1].y = XtHeight(w) / w->strip_chart.scale; + } +} diff --git a/src/Text.c b/src/Text.c new file mode 100644 index 0000000..a1ae74a --- /dev/null +++ b/src/Text.c @@ -0,0 +1,4157 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Copyright (c) 1998 by The XFree86 Project, Inc. + * + * 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 XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" +#include "XawI18n.h" + +#ifndef MAX_LEN_CT +#define MAX_LEN_CT 6 /* for sequence: ESC $ ( A \xx \xx */ +#endif + +unsigned long FMT8BIT = 0L; +unsigned long XawFmt8Bit = 0L; +unsigned long XawFmtWide = 0L; + +#define SinkClearToBG _XawTextSinkClearToBackground + +#define SrcScan XawTextSourceScan +#define SrcRead XawTextSourceRead +#define SrcReplace XawTextSourceReplace +#define SrcSearch XawTextSourceSearch +#define SrcCvtSel XawTextSourceConvertSelection +#define SrcSetSelection XawTextSourceSetSelection + +#define MULTI_CLICK_TIME 500L + +#define SRC_CHANGE_NONE 0 +#define SRC_CHANGE_AFTER 1 +#define SRC_CHANGE_BEFORE 2 +#define SRC_CHANGE_OVERLAP 3 + +#define Superclass (&simpleClassRec) + +/* + * Compute a the maximum length of a cut buffer that we can pass at any + * time. The 64 allows for the overhead of the Change Property request. + */ +#define MAX_CUT_LEN(dpy) (XMaxRequestSize(dpy) - 64) + +#define ClearWindow(ctx) \ + _XawTextNeedsUpdating((ctx), \ + (ctx)->text.lt.top, \ + (ctx)->text.lt.info[ctx->text.lt.lines].position) + +/* + * Class Methods + */ +static void XawTextClassInitialize(void); +static void XawTextInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawTextRealize(Widget, XtValueMask*, XSetWindowAttributes*); +static void XawTextDestroy(Widget); +static void XawTextResize(Widget); +static void XawTextExpose(Widget, XEvent*, Region); +static Boolean XawTextSetValues(Widget, Widget, Widget, ArgList, Cardinal*); +static void XawTextGetValuesHook(Widget, ArgList, Cardinal*); +static Bool XawTextChangeSensitive(Widget); + +/* + * Prototypes + */ +static XawTextPosition _BuildLineTable(TextWidget, XawTextPosition, int); +static void _CreateCutBuffers(Display*); +static Boolean TextConvertSelection(Widget, Atom*, Atom*, Atom*, XtPointer*, + unsigned long*, int*); +static int CountLines(TextWidget, XawTextPosition, XawTextPosition); +static void CreateHScrollBar(TextWidget); +static void CreateVScrollBar(TextWidget); +static void CvtStringToScrollMode(XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr); +static Boolean CvtScrollModeToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static void CvtStringToWrapMode(XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr); +static Boolean CvtWrapModeToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean CvtStringToJustifyMode(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean CvtJustifyModeToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static void DestroyHScrollBar(TextWidget); +static void DestroyVScrollBar(TextWidget); +#ifndef OLDXAW +static void DisplayText(Widget, XawTextPosition, XawTextPosition); +#endif +static void OldDisplayText(Widget, XawTextPosition, XawTextPosition); +static void DisplayTextWindow(Widget); +static void DoCopyArea(TextWidget, int, int, unsigned int, unsigned int, + int, int); +static void DoSelection(TextWidget, XawTextPosition, Time, Bool); +static void ExtendSelection(TextWidget, XawTextPosition, Bool); +static XawTextPosition FindGoodPosition(TextWidget, XawTextPosition); +static void FlushUpdate(TextWidget); +static int GetCutBufferNumber(Atom); +static int GetMaxTextWidth(TextWidget); +static unsigned int GetWidestLine(TextWidget); +static void HScroll(Widget, XtPointer, XtPointer); +static void HJump(Widget, XtPointer, XtPointer); +static void InsertCursor(Widget, XawTextInsertState); +static Bool LineAndXYForPosition(TextWidget, XawTextPosition, int*, + int*, int*); +static int LineForPosition(TextWidget, XawTextPosition); +static void TextLoseSelection(Widget, Atom*); +static Bool MatchSelection(Atom, XawTextSelection*); +static void ModifySelection(TextWidget, XawTextPosition, XawTextPosition); +static XawTextPosition PositionForXY(TextWidget, int, int); +static void PositionHScrollBar(TextWidget); +static void PositionVScrollBar(TextWidget); +#ifndef OLDXAW +static int ResolveColumnNumber(TextWidget); +static int ResolveLineNumber(TextWidget); +#endif +static void _SetSelection(TextWidget, XawTextPosition, XawTextPosition, + Atom*, Cardinal); +static void TextSinkResize(Widget); +static void UpdateTextInRectangle(TextWidget, XRectangle*); +static void UpdateTextInLine(TextWidget, int, int, int); +static void VScroll(Widget, XtPointer, XtPointer); +static void VJump(Widget, XtPointer, XtPointer); + +/* + * External + */ +void _XawTextAlterSelection(TextWidget, + XawTextSelectionMode, XawTextSelectionAction, + String*, Cardinal*); +void _XawTextCheckResize(TextWidget); +void _XawTextClearAndCenterDisplay(TextWidget); +void _XawTextExecuteUpdate(TextWidget); +char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition); +void _XawTextPrepareToUpdate(TextWidget); +int _XawTextReplace(TextWidget, XawTextPosition, XawTextPosition, + XawTextBlock*); +Atom *_XawTextSelectionList(TextWidget, String*, Cardinal); +void _XawTextSetScrollBars(TextWidget); +void _XawTextSetSelection(TextWidget, XawTextPosition, XawTextPosition, + String*, Cardinal); +void _XawTextVScroll(TextWidget, int); +void XawTextScroll(TextWidget, int, int); +void _XawTextSetSource(Widget, Widget, XawTextPosition, XawTextPosition); +#ifndef OLDXAW +void _XawTextSetLineAndColumnNumber(TextWidget, Bool); +#endif +void _XawTextSourceChanged(Widget, XawTextPosition, XawTextPosition, + XawTextBlock*, int); + +/* Not used by other modules, but were extern on previous versions + * of the library + */ +void _XawTextShowPosition(TextWidget); + +/* + * From TextAction.c + */ +extern void _XawTextZapSelection(TextWidget, XEvent*, Bool); + +/* + * From TextSrc.c + */ +void _XawSourceAddText(Widget, Widget); +void _XawSourceRemoveText(Widget, Widget, Bool); +Bool _XawTextSourceNewLineAtEOF(Widget); + +/* + * From TextSink.c + */ +void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned); +void _XawTextSinkDisplayText(Widget, int, int, XawTextPosition, XawTextPosition, + Bool); + +/**************************************************************** + * + * Full class record constant + * + ****************************************************************/ +/* + * From TextTr.c + */ +static XawTextSelectType defaultSelectTypes[] = { + XawselectPosition, XawselectAlphaNumeric, XawselectWord, XawselectLine, + XawselectParagraph, XawselectAll, XawselectNull, +}; + +static XPointer defaultSelectTypesPtr = (XPointer)defaultSelectTypes; +static Dimension defWidth = 100; +static Dimension defHeight = DEFAULT_TEXT_HEIGHT; + +#define offset(field) XtOffsetOf(TextRec, field) +static XtResource resources[] = { + { + XtNwidth, + XtCWidth, + XtRDimension, + sizeof(Dimension), + offset(core.width), + XtRDimension, + (XtPointer)&defWidth + }, + { + XtNcursor, + XtCCursor, + XtRCursor, + sizeof(Cursor), + offset(simple.cursor), + XtRString, + "xterm" + }, + { + XtNheight, + XtCHeight, + XtRDimension, + sizeof(Dimension), + offset(core.height), + XtRDimension, + (XtPointer)&defHeight + }, + { + XtNdisplayPosition, + XtCTextPosition, + XtRInt, + sizeof(XawTextPosition), + offset(text.lt.top), + XtRImmediate, + (XtPointer)0 + }, + { + XtNinsertPosition, + XtCTextPosition, + XtRInt, + sizeof(XawTextPosition), + offset(text.insertPos), + XtRImmediate, + (XtPointer)0 + }, + { + XtNleftMargin, + XtCMargin, + XtRPosition, + sizeof(Position), + offset(text.r_margin.left), + XtRImmediate, + (XtPointer)2 + }, + { + XtNrightMargin, + XtCMargin, + XtRPosition, + sizeof(Position), + offset(text.r_margin.right), + XtRImmediate, + (XtPointer)4 + }, + { + XtNtopMargin, + XtCMargin, + XtRPosition, + sizeof(Position), + offset(text.r_margin.top), + XtRImmediate, + (XtPointer)2 + }, + { + XtNbottomMargin, + XtCMargin, + XtRPosition, + sizeof(Position), + offset(text.r_margin.bottom), + XtRImmediate, + (XtPointer)2 + }, + { + XtNselectTypes, + XtCSelectTypes, + XtRPointer, + sizeof(XawTextSelectType*), + offset(text.sarray), + XtRPointer, + (XtPointer)&defaultSelectTypesPtr + }, + { + XtNtextSource, + XtCTextSource, + XtRWidget, + sizeof(Widget), + offset(text.source), + XtRImmediate, + NULL + }, + { + XtNtextSink, + XtCTextSink, + XtRWidget, + sizeof(Widget), + offset(text.sink), + XtRImmediate, + NULL + }, + { + XtNdisplayCaret, + XtCOutput, + XtRBoolean, + sizeof(Boolean), + offset(text.display_caret), + XtRImmediate, + (XtPointer)True + }, + { + XtNscrollVertical, + XtCScroll, + XtRScrollMode, + sizeof(XawTextScrollMode), + offset(text.scroll_vert), + XtRImmediate, + (XtPointer)False + }, + { + XtNscrollHorizontal, + XtCScroll, + XtRScrollMode, + sizeof(XawTextScrollMode), + offset(text.scroll_horiz), + XtRImmediate, + (XtPointer)False + }, + { + XtNwrap, + XtCWrap, + XtRWrapMode, + sizeof(XawTextWrapMode), + offset(text.wrap), + XtRImmediate, + (XtPointer)XawtextWrapNever + }, + { + XtNautoFill, + XtCAutoFill, + XtRBoolean, + sizeof(Boolean), + offset(text.auto_fill), + XtRImmediate, + (XtPointer)False + }, +#ifndef OLDXAW + { + XtNpositionCallback, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + offset(text.position_callbacks), + XtRCallback, + NULL + }, + { + XtNleftColumn, + XtCColumn, + XtRShort, + sizeof(short), + offset(text.left_column), + XtRImmediate, + (XtPointer)0 + }, + { + XtNrightColumn, + XtCColumn, + XtRShort, + sizeof(short), + offset(text.right_column), + XtRImmediate, + (XtPointer)0 + }, + { + XtNjustifyMode, + XtCJustifyMode, + XtRJustifyMode, + sizeof(XawTextJustifyMode), + offset(text.justify), + XtRImmediate, + (XtPointer)XawjustifyLeft + }, +#endif /* OLDXAW */ +}; +#undef offset + +#define done(address, type) \ + { toVal->size = sizeof(type); toVal->addr = (XPointer)address; } + +static XrmQuark QWrapNever, QWrapLine, QWrapWord; +#ifndef notdef +static XrmQuark QScrollNever, QScrollWhenNeeded, QScrollAlways; +#endif +static XrmQuark QJustifyLeft, QJustifyRight, QJustifyCenter, QJustifyFull; + +/*ARGSUSED*/ +static void +CvtStringToScrollMode(XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal) +{ + static XawTextScrollMode scrollMode = XawtextScrollNever; + XrmQuark q; + char name[32]; + + XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name)); + q = XrmStringToQuark(name); + + if (q == QScrollNever || q == QScrollWhenNeeded) + scrollMode = XawtextScrollNever; + else if (q == QScrollAlways) + scrollMode = XawtextScrollAlways; + else if (strcmp(name, "true") == 0 || strcmp(name, "1") == 0) + scrollMode = XawtextScrollAlways; + else if (strcmp(name, "false") == 0 || strcmp(name, "0") == 0) + scrollMode = XawtextScrollNever; + else + XtStringConversionWarning((char *)fromVal->addr, XtRScrollMode); + + done(&scrollMode, XawTextScrollMode); +} + +/*ARGSUSED*/ +static Boolean +CvtScrollModeToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, XtPointer *data) +{ + static char *buffer; + Cardinal size; + + switch (*(XawTextScrollMode *)fromVal->addr) { + case XawtextScrollNever: + case XawtextScrollWhenNeeded: + buffer = XtEtextScrollNever; + break; + case XawtextScrollAlways: + buffer = XtEtextScrollAlways; + break; + default: + XawTypeToStringWarning(dpy, XtRScrollMode); + toVal->addr = NULL; + toVal->size = 0; + return (False); + } + size = strlen(buffer) + 1; + if (toVal->addr != NULL) { + if (toVal->size < size) { + toVal->size = size; + return (False); + } + strcpy((char *)toVal->addr, buffer); + } + else + toVal->addr = (XPointer)buffer; + toVal->size = sizeof(String); + + return (True); +} + +/*ARGSUSED*/ +static void +CvtStringToWrapMode(XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal) +{ + static XawTextWrapMode wrapMode = XawtextWrapNever; + XrmQuark q; + char lowerName[6]; + + XmuNCopyISOLatin1Lowered(lowerName, (char *)fromVal->addr, + sizeof(lowerName)); + q = XrmStringToQuark(lowerName); + + if (q == QWrapNever) + wrapMode = XawtextWrapNever; + else if (q == QWrapLine) + wrapMode = XawtextWrapLine; + else if (q == QWrapWord) + wrapMode = XawtextWrapWord; + else + XtStringConversionWarning((char *)fromVal->addr, XtRWrapMode); + + done(&wrapMode, XawTextWrapMode); +} + +/*ARGSUSED*/ +static Boolean +CvtWrapModeToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, XtPointer *data) +{ + static char *buffer; + Cardinal size; + + switch (*(XawTextWrapMode *)fromVal->addr) { + case XawtextWrapNever: + buffer = XtEtextWrapNever; + break; + case XawtextWrapLine: + buffer = XtEtextWrapLine; + break; + case XawtextWrapWord: + buffer = XtEtextWrapWord; + break; + default: + XawTypeToStringWarning(dpy, XtRWrapMode); + toVal->addr = NULL; + toVal->size = 0; + return (False); + } + size = strlen(buffer) + 1; + if (toVal->addr != NULL) { + if (toVal->size < size) { + toVal->size = size; + return (False); + } + strcpy((char *)toVal->addr, buffer); + } + else + toVal->addr = (XPointer)buffer; + toVal->size = sizeof(String); + + return (True); +} + +/*ARGSUSED*/ +static Boolean +CvtStringToJustifyMode(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, XtPointer *data) +{ + XawTextJustifyMode justify; + XrmQuark q; + char lowerName[8]; + + XmuNCopyISOLatin1Lowered(lowerName, (char *)fromVal->addr, + sizeof(lowerName)); + q = XrmStringToQuark(lowerName); + + if (q == QJustifyLeft) + justify = XawjustifyLeft; + else if (q == QJustifyRight) + justify = XawjustifyRight; + else if (q == QJustifyCenter) + justify = XawjustifyCenter; + else if(q == QJustifyFull) + justify = XawjustifyFull; + else { + XtStringConversionWarning((char *)fromVal->addr, XtRJustifyMode); + return (False); + } + + toVal->size = sizeof(XawTextJustifyMode); + *(XawTextJustifyMode *)(toVal->addr) = justify; + + return (True); +} + + +/*ARGSUSED*/ +static Boolean +CvtJustifyModeToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, XtPointer *data) +{ + static char *buffer; + Cardinal size; + + switch (*(XawTextJustifyMode *)fromVal->addr) { + case XawjustifyLeft: + buffer = XtEtextJustifyLeft; + break; + case XawjustifyRight: + buffer = XtEtextJustifyRight; + break; + case XawjustifyCenter: + buffer = XtEtextJustifyCenter; + break; + case XawjustifyFull: + buffer = XtEtextJustifyFull; + break; + default: + XawTypeToStringWarning(dpy, XtRJustifyMode); + toVal->addr = NULL; + toVal->size = 0; + return (False); + } + size = strlen(buffer) + 1; + if (toVal->addr != NULL) { + if (toVal->size < size) { + toVal->size = size; + return (False); + } + strcpy((char *)toVal->addr, buffer); + } + else + toVal->addr = (XPointer)buffer; + toVal->size = sizeof(String); + + return (True); +} + +#undef done + +static void +XawTextClassInitialize(void) +{ + if (!XawFmt8Bit) + FMT8BIT = XawFmt8Bit = XrmPermStringToQuark("FMT8BIT"); + if (!XawFmtWide) + XawFmtWide = XrmPermStringToQuark("FMTWIDE"); + + XawInitializeWidgetSet(); + + textClassRec.core_class.num_actions = _XawTextActionsTableCount; + + QWrapNever = XrmPermStringToQuark(XtEtextWrapNever); + QWrapLine = XrmPermStringToQuark(XtEtextWrapLine); + QWrapWord = XrmPermStringToQuark(XtEtextWrapWord); + XtAddConverter(XtRString, XtRWrapMode, CvtStringToWrapMode, NULL, 0); + XtSetTypeConverter(XtRWrapMode, XtRString, CvtWrapModeToString, + NULL, 0, XtCacheNone, NULL); + QScrollNever = XrmPermStringToQuark(XtEtextScrollNever); + QScrollWhenNeeded = XrmPermStringToQuark(XtEtextScrollWhenNeeded); + QScrollAlways = XrmPermStringToQuark(XtEtextScrollAlways); + XtAddConverter(XtRString, XtRScrollMode, CvtStringToScrollMode, + NULL, 0); + XtSetTypeConverter(XtRScrollMode, XtRString, CvtScrollModeToString, + NULL, 0, XtCacheNone, NULL); + QJustifyLeft = XrmPermStringToQuark(XtEtextJustifyLeft); + QJustifyRight = XrmPermStringToQuark(XtEtextJustifyRight); + QJustifyCenter = XrmPermStringToQuark(XtEtextJustifyCenter); + QJustifyFull = XrmPermStringToQuark(XtEtextJustifyFull); + XtSetTypeConverter(XtRString, XtRJustifyMode, CvtStringToJustifyMode, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRJustifyMode, XtRString, CvtJustifyModeToString, + NULL, 0, XtCacheNone, NULL); +} + +/* + * Function: + * PositionHScrollBar + * + * Parameters: + * ctx - text widget + * + * Description: + * Positions the Horizontal scrollbar. + */ +static void +PositionHScrollBar(TextWidget ctx) +{ + Widget hbar = ctx->text.hbar, vbar = ctx->text.vbar; + Position x, y; + Dimension width, height; + + if (ctx->text.hbar == NULL) + return; + + if (vbar != NULL) + x = XtWidth(vbar); + else + x = -XtBorderWidth(hbar); + y = XtHeight(ctx) - XtHeight(hbar) - XtBorderWidth(hbar); + if (vbar != NULL) { + width = XtWidth(ctx) - XtWidth(vbar) - XtBorderWidth(vbar); + if (width > XtWidth(ctx)) + width = XtWidth(ctx); + } + else + width = XtWidth(ctx); + height = XtHeight(hbar); + + XtConfigureWidget(hbar, x, y, width, height, XtBorderWidth(hbar)); +} + +/* + * Function: + * PositionVScrollBar + * + * Parameters: + * ctx - text widget + * + * Description: + * Positions the Vertical scrollbar. + */ +static void +PositionVScrollBar(TextWidget ctx) +{ + Widget vbar = ctx->text.vbar; + Position x, y; + Dimension width, height; + + if (vbar == NULL) + return; + + x = y = -XtBorderWidth(vbar); + height = XtHeight(ctx); + width = XtWidth(vbar); + + XtConfigureWidget(vbar, x, y, width, height, XtBorderWidth(vbar)); +} + +static void +CreateVScrollBar(TextWidget ctx) +{ + Widget vbar; + + if (ctx->text.vbar != NULL) + return; + + ctx->text.vbar = vbar = + XtCreateWidget("vScrollbar", scrollbarWidgetClass, (Widget)ctx, NULL, 0); + XtAddCallback(vbar, XtNscrollProc, VScroll, (XtPointer)ctx); + XtAddCallback(vbar, XtNjumpProc, VJump, (XtPointer)ctx); + + ctx->text.r_margin.left += XtWidth(vbar) + XtBorderWidth(vbar); + ctx->text.left_margin = ctx->text.margin.left = ctx->text.r_margin.left; + + PositionVScrollBar(ctx); + PositionHScrollBar(ctx); + TextSinkResize(ctx->text.sink); + + if (XtIsRealized((Widget)ctx)) { + XtRealizeWidget(vbar); + XtMapWidget(vbar); + } + XtSetKeyboardFocus(vbar, (Widget)ctx); +} + +/* + * Function: + * DestroyVScrollBar + * + * Parameters: + * ctx - parent text widget + * + * Description: + * Removes vertical ScrollBar. + */ +static void +DestroyVScrollBar(TextWidget ctx) +{ + Widget vbar = ctx->text.vbar; + + if (vbar == NULL) + return; + + ctx->text.r_margin.left -= XtWidth(vbar) + XtBorderWidth(vbar); + ctx->text.left_margin = ctx->text.margin.left = ctx->text.r_margin.left; + + XtDestroyWidget(vbar); + ctx->text.vbar = NULL; + if (!ctx->core.being_destroyed) { + PositionHScrollBar(ctx); + TextSinkResize(ctx->text.sink); + } +} + +static void +CreateHScrollBar(TextWidget ctx) +{ + Arg args[1]; + Widget hbar; + int bottom; + + if (ctx->text.hbar != NULL) + return; + + XtSetArg(args[0], XtNorientation, XtorientHorizontal); + ctx->text.hbar = hbar = + XtCreateWidget("hScrollbar", scrollbarWidgetClass, (Widget)ctx, args, 1); + XtAddCallback(hbar, XtNscrollProc, HScroll, (XtPointer)ctx); + XtAddCallback(hbar, XtNjumpProc, HJump, (XtPointer)ctx); + + bottom = ctx->text.r_margin.bottom + XtHeight(hbar) + XtBorderWidth(hbar); + + ctx->text.margin.bottom = ctx->text.r_margin.bottom = bottom; + + PositionHScrollBar(ctx); + TextSinkResize(ctx->text.sink); + + if (XtIsRealized((Widget)ctx)) { + XtRealizeWidget(hbar); + XtMapWidget(hbar); + } + XtSetKeyboardFocus(hbar, (Widget)ctx); +} + +/* + * Function: + * DestroyHScrollBar + * + * Parameters: + * ctx - parent text widget + * + * Description: + * Removes horizontal ScrollBar. + */ +static void +DestroyHScrollBar(TextWidget ctx) +{ + Widget hbar = ctx->text.hbar; + + if (hbar == NULL) + return; + + ctx->text.r_margin.bottom -= XtHeight(hbar) + XtBorderWidth(hbar); + ctx->text.margin.bottom = ctx->text.r_margin.bottom; + + XtDestroyWidget(hbar); + ctx->text.hbar = NULL; + if (!ctx->core.being_destroyed) + TextSinkResize(ctx->text.sink); +} + +/*ARGSUSED*/ +static void +XawTextInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + TextWidget ctx = (TextWidget)cnew; + + ctx->text.lt.lines = 0; + ctx->text.lt.info = (XawTextLineTableEntry *) + XtCalloc(1, sizeof(XawTextLineTableEntry)); +#ifndef OLDXAW + ctx->text.lt.base_line = 1; +#endif + (void)bzero(&ctx->text.origSel, sizeof(XawTextSelection)); + (void)bzero(&ctx->text.s, sizeof(XawTextSelection)); + ctx->text.s.type = XawselectPosition; + ctx->text.salt = NULL; + ctx->text.hbar = ctx->text.vbar = NULL; + ctx->text.lasttime = 0; + ctx->text.time = 0; + ctx->text.showposition = True; + ctx->text.lastPos = ctx->text.source != NULL ? + XawTextGetLastPosition(ctx) : 0; + ctx->text.file_insert = NULL; + ctx->text.search = NULL; + ctx->text.update = XmuNewScanline(0, 0, 0); + ctx->text.gc = XtGetGC(cnew, 0, 0); + ctx->text.hasfocus = False; + ctx->text.margin = ctx->text.r_margin; /* Strucure copy */ + ctx->text.left_margin = ctx->text.r_margin.left; + ctx->text.update_disabled = False; + ctx->text.clear_to_eol = True; + ctx->text.old_insert = -1; + ctx->text.mult = 1; + ctx->text.salt2 = NULL; + ctx->text.from_left = -1; + +#ifndef OLDXAW + ctx->text.numeric = False; + ctx->text.selection_state = False; + ctx->text.kill_ring = 0; + + ctx->text.line_number = -1; + ctx->text.column_number = -1; + ctx->text.source_changed = SRC_CHANGE_NONE; + + ctx->text.kill_ring_ptr = NULL; + ctx->text.overwrite = False; +#endif + + if (XtHeight(ctx) == DEFAULT_TEXT_HEIGHT) { + XtHeight(ctx) = VMargins(ctx); + if (ctx->text.sink != NULL) + XtHeight(ctx) += XawTextSinkMaxHeight(ctx->text.sink, 1); + } + + if (ctx->text.scroll_vert == XawtextScrollAlways) + CreateVScrollBar(ctx); + if (ctx->text.scroll_horiz == XawtextScrollAlways) + CreateHScrollBar(ctx); + +#ifndef OLDXAW + if (ctx->text.left_column < 0) + ctx->text.left_column = 0; + if (ctx->text.right_column < 0) + ctx->text.right_column = 0; +#endif +} + +static void +XawTextRealize(Widget w, XtValueMask *mask, XSetWindowAttributes *attr) +{ + TextWidget ctx = (TextWidget)w; + + (*textClassRec.core_class.superclass->core_class.realize)(w, mask, attr); + + if (ctx->text.hbar != NULL) { + XtRealizeWidget(ctx->text.hbar); + XtMapWidget(ctx->text.hbar); + } + + if (ctx->text.vbar != NULL) { + XtRealizeWidget(ctx->text.vbar); + XtMapWidget(ctx->text.vbar); + } + + _XawTextBuildLineTable(ctx, ctx->text.lt.top, True); + +#ifndef OLDXAW + _XawTextSetLineAndColumnNumber(ctx, True); +#endif +} + +/* Utility routines for support of Text */ +static void +_CreateCutBuffers(Display *d) +{ + static struct _DisplayRec { + struct _DisplayRec *next; + Display *dpy; + } *dpy_list = NULL; + struct _DisplayRec *dpy_ptr; + + for (dpy_ptr = dpy_list; dpy_ptr != NULL; dpy_ptr = dpy_ptr->next) + if (dpy_ptr->dpy == d) + return; + + dpy_ptr = XtNew(struct _DisplayRec); + dpy_ptr->next = dpy_list; + dpy_ptr->dpy = d; + dpy_list = dpy_ptr; + +#define Create(buffer) \ + XChangeProperty(d, RootWindow(d, 0), buffer, XA_STRING, 8, \ + PropModeAppend, NULL, 0); + + Create(XA_CUT_BUFFER0); + Create(XA_CUT_BUFFER1); + Create(XA_CUT_BUFFER2); + Create(XA_CUT_BUFFER3); + Create(XA_CUT_BUFFER4); + Create(XA_CUT_BUFFER5); + Create(XA_CUT_BUFFER6); + Create(XA_CUT_BUFFER7); + +#undef Create +} + +/* + * Procedure to manage insert cursor visibility for editable text. It uses + * the value of ctx->insertPos and an implicit argument. In the event that + * position is immediately preceded by an eol graphic, then the insert cursor + * is displayed at the beginning of the next line. + */ +static void +InsertCursor(Widget w, XawTextInsertState state) +{ + TextWidget ctx = (TextWidget)w; + int x, y; + int line; + + if (ctx->text.lt.lines < 1) + return; + + if (ctx->text.display_caret && + LineAndXYForPosition(ctx, ctx->text.insertPos, &line, &x, &y)) { + if (line < ctx->text.lt.lines) + y += (ctx->text.lt.info[line + 1].y - ctx->text.lt.info[line].y) + 1; + else + y += (ctx->text.lt.info[line].y - ctx->text.lt.info[line - 1].y) + 1; + + XawTextSinkInsertCursor(ctx->text.sink, x, y, state); + } + + /* Keep Input Method up to speed */ + if (ctx->simple.international) { + Arg list[1]; + + XtSetArg(list[0], XtNinsertPosition, ctx->text.insertPos); + _XawImSetValues(w, list, 1); + } +} + +/* + * Procedure to register a span of text that is no longer valid on the display + * It is used to avoid a number of small, and potentially overlapping, screen + * updates. +*/ +void +_XawTextNeedsUpdating(TextWidget ctx, + XawTextPosition left, XawTextPosition right) +{ + XmuSegment segment; + + if (left >= right) + return; + + segment.x1 = (int)left; + segment.x2 = (int)right; + (void)XmuScanlineOrSegment(ctx->text.update, &segment); +} + +/* + * Procedure to read a span of text in Ascii form. This is purely a hack and + * we probably need to add a function to sources to provide this functionality. + * [note: this is really a private procedure but is used in multiple modules]. + */ +char * +_XawTextGetText(TextWidget ctx, XawTextPosition left, XawTextPosition right) +{ + char *result, *tempResult; + XawTextBlock text; + int bytes; + + if (XawTextFormat(ctx, XawFmt8Bit)) + bytes = sizeof(unsigned char); + else if (XawTextFormat(ctx, XawFmtWide)) + bytes = sizeof(wchar_t); + else /* if there is another fomat, add here */ + bytes = 1; + + /* leave space for ZERO */ + tempResult = result = XtMalloc((unsigned)(right - left + ONE) * bytes); + + while (left < right) { + left = SrcRead(ctx->text.source, left, &text, (int)(right - left)); + if (!text.length) + break; + memmove(tempResult, text.ptr, (unsigned)(text.length * bytes)); + tempResult += text.length * bytes; + } + + if (bytes == sizeof(wchar_t)) + *((wchar_t*)tempResult) = (wchar_t)0; + else + *tempResult = '\0'; + + return (result); +} + +/* Like _XawTextGetText, but enforces ICCCM STRING type encoding. This + * routine is currently used to put just the ASCII chars in the selection + * into a cut buffer. + */ +char * +_XawTextGetSTRING(TextWidget ctx, XawTextPosition left, XawTextPosition right) +{ + unsigned char *s; + unsigned char c; + long i, j, n; + wchar_t *ws, wc; + + /* allow ESC in accordance with ICCCM */ + if (XawTextFormat(ctx, XawFmtWide)) { + MultiSinkObject sink = (MultiSinkObject)ctx->text.sink; + ws = (wchar_t *)_XawTextGetText(ctx, left, right); + n = wcslen(ws); + for (j = 0, i = 0; j < n; j++) { + wc = ws[j]; + if (XwcTextEscapement (sink->multi_sink.fontset, &wc, 1) + || (wc == _Xaw_atowc(XawTAB)) || (wc == _Xaw_atowc(XawLF)) + || (wc == _Xaw_atowc(XawESC))) + ws[i++] = wc; + } + ws[i] = (wchar_t)0; + return ((char *)ws); + } + else { + s = (unsigned char *)_XawTextGetText(ctx, left, right); + /* only HT and NL control chars are allowed, strip out others */ + n = strlen((char *)s); + i = 0; + for (j = 0; j < n; j++) { + c = s[j]; + if (((c >= 0x20) && c <= 0x7f) + ||(c >= 0xa0) || (c == XawTAB) || (c == XawLF) + || (c == XawESC)) { + s[i] = c; + i++; + } + } + s[i] = 0; + + return ((char *)s); + } +} + +/* + * This routine maps an x and y position in a window that is displaying text + * into the corresponding position in the source. + */ +static XawTextPosition +PositionForXY(TextWidget ctx, int x, int y) +{ + int fromx, line, width, height; + XawTextPosition position; + + if (ctx->text.lt.lines == 0) + return (0); + + for (line = 0; line < ctx->text.lt.lines - 1; line++) { + if (y <= ctx->text.lt.info[line + 1].y) + break; + } + position = ctx->text.lt.info[line].position; + if (position >= ctx->text.lastPos) + return (ctx->text.lastPos); + fromx = ctx->text.left_margin; + XawTextSinkFindPosition(ctx->text.sink, position, fromx, x - fromx, + False, &position, &width, &height); + + if (position > ctx->text.lastPos) + return (ctx->text.lastPos); + + if (position >= ctx->text.lt.info[line + 1].position) + position = SrcScan(ctx->text.source, ctx->text.lt.info[line + 1].position, + XawstPositions, XawsdLeft, 1, True); + + return (position); +} + +/* + * This routine maps a source position in to the corresponding line number + * of the text that is displayed in the window. + */ +static int +LineForPosition(TextWidget ctx, XawTextPosition position) +{ + int line; + + for (line = 0; line < ctx->text.lt.lines; line++) + if (position < ctx->text.lt.info[line + 1].position) + break; + + return (line); +} + +/* + * This routine maps a source position into the corresponding line number + * and the x, y coordinates of the text that is displayed in the window. + */ +static Bool +LineAndXYForPosition(TextWidget ctx, XawTextPosition pos, + int *line, int *x, int *y) +{ + XawTextPosition linePos, endPos; + Boolean visible; + int realW, realH; + + *line = 0; + *x = ctx->text.left_margin; + *y = ctx->text.margin.top + 1; + if ((visible = IsPositionVisible(ctx, pos)) != False) { + *line = LineForPosition(ctx, pos); + *y = ctx->text.lt.info[*line].y; + linePos = ctx->text.lt.info[*line].position; + XawTextSinkFindDistance(ctx->text.sink, linePos, + *x, pos, &realW, &endPos, &realH); + *x += realW; + } + + return (visible); +} + +/* + * This routine builds a line table. It does this by starting at the + * specified position and measuring text to determine the staring position + * of each line to be displayed. It also determines and saves in the + * linetable all the required metrics for displaying a given line (e.g. + * x offset, y offset, line length, etc.). + */ +void +_XawTextBuildLineTable(TextWidget ctx, XawTextPosition position, + _XtBoolean force_rebuild) +{ + Dimension height = 0; + int lines = 0; + Cardinal size; + + if ((int)XtHeight(ctx) > VMargins(ctx)) { + height = XtHeight(ctx) - VMargins(ctx); + lines = XawTextSinkMaxLines(ctx->text.sink, height); + } + size = sizeof(XawTextLineTableEntry) * (lines + 1); + + if (lines != ctx->text.lt.lines || ctx->text.lt.info == NULL) { + ctx->text.lt.info = (XawTextLineTableEntry *) + XtRealloc((char *)ctx->text.lt.info, size); + ctx->text.lt.lines = lines; + force_rebuild = True; + } + + if (force_rebuild) { + (void)bzero((char *)ctx->text.lt.info, size); + /* force a text update in the first text line if it is visible */ + ctx->text.lt.info[0].position = (XawTextPosition)-1; + } + if (position != ctx->text.lt.info[0].position) { + (void)_BuildLineTable(ctx, position, 0); + ctx->text.clear_to_eol = True; + } +} + +/* + * We may need to resize the line table here, since there maybe lines with + * different fonts (that can be shorter or taller than the default one) + */ +static XawTextPosition +_BuildLineTable(TextWidget ctx, XawTextPosition position, int line) +{ + XawTextLineTableEntry *lt = ctx->text.lt.info + line; + XawTextPosition end, update_from = -1; + Position y; + int wwidth, width, height; +#ifndef OLDXAW + Widget src = ctx->text.source; +#endif + int max_y = (int)XtHeight(ctx) - (int)ctx->text.margin.bottom; + + if (ctx->text.wrap == XawtextWrapNever) + wwidth = 0x7fffffff; + else + wwidth = GetMaxTextWidth(ctx); + + /* XXX y may change, due to font size changes. See later */ + y = line == 0 ? ctx->text.margin.top : lt->y; + +#ifndef OLDXAW + if (ctx->text.lt.base_line < 0) { + if (line == 0) + ctx->text.lt.top = position; + } + else if (line == 0) { + XawTextPosition pos = ctx->text.lt.top; + int base_line = ctx->text.lt.base_line; + + if (position == 0) + base_line = 1; + else if (ctx->text.lt.base_line == 0 || + ctx->text.source_changed == SRC_CHANGE_OVERLAP) { + pos = 0; + base_line = 1; + + while (pos < position) { + pos = SrcScan(src, pos, XawstEOL, XawsdRight, 1, True); + if (pos <= position) { + ++base_line; + if (pos == ctx->text.lastPos) { + base_line -= !_XawTextSourceNewLineAtEOF(src); + break; + } + } + } + } + else if (ctx->text.wrap == XawtextWrapNever + && IsPositionVisible(ctx, position)) + base_line += LineForPosition(ctx, position); + else if (pos < position) { + while (pos < position) { + pos = SrcScan(src, pos, XawstEOL, XawsdRight, 1, True); + if (pos <= position) { + ++base_line; + if (pos == ctx->text.lastPos) { + base_line -= !_XawTextSourceNewLineAtEOF(src); + break; + } + } + } + } + else if (pos > position) { + while (pos > position) { + pos = SrcScan(src, pos, XawstEOL, XawsdLeft, 1, False); + if (--pos >= position) + --base_line; + } + } + + ctx->text.lt.top = position; + ctx->text.lt.base_line = base_line; + } +#else + if (line == 0) + ctx->text.lt.top = position; +#endif + + /* CONSTCOND */ + while (True) { + XawTextSinkFindPosition(ctx->text.sink, position, ctx->text.left_margin, + wwidth, ctx->text.wrap == XawtextWrapWord, + &end, &width, &height); + + if (lt->position != position) { + _XawTextNeedsUpdating(ctx, position, + end <= position ? position + 1 : end); + ctx->text.clear_to_eol = True; + lt->position = position; + } + if (lt->y != y) { + if (update_from < 0) + update_from = line == 0 ? + ctx->text.lt.info[0].position : + ctx->text.lt.info[line - 1].position; + lt->y = y; + ctx->text.clear_to_eol = True; + } + if (lt->textWidth != width) { + if (lt->textWidth > width) + ctx->text.clear_to_eol = True; + lt->textWidth = width; + } + y += height; + + if (end > ctx->text.lastPos) { + position = end; + ctx->text.clear_to_eol = True; + _XawTextNeedsUpdating(ctx, end, end + ctx->text.lt.lines - line); + while (line++ < ctx->text.lt.lines) { + if (line > 1 && y > max_y) { + ctx->text.lt.lines = line - 1; + break; + } + ++lt; + if (lt->y != y) { + if (update_from < 0) + update_from = line < 2 ? + ctx->text.lt.info[0].position : + ctx->text.lt.info[line - 2].position; + lt->y = y; + } + lt->position = ++position; + lt->textWidth = 0; + y += height; + } + if (update_from >= 0) + _XawTextNeedsUpdating(ctx, update_from, + ctx->text.lt.info[ctx->text.lt.lines].position); + _XawTextSetScrollBars(ctx); + + return (ctx->text.lastPos); + } + + if (line && y > max_y) + /* will return in the next loop */ + ctx->text.lt.lines = line; + + if (++line > ctx->text.lt.lines && y < max_y) { + /* grow the line table */ + ctx->text.lt.info = (XawTextLineTableEntry *) + XtRealloc((char *)ctx->text.lt.info, + sizeof(XawTextLineTableEntry) * (line + 1)); + lt = ctx->text.lt.info + line; + bzero(lt, sizeof(XawTextLineTableEntry)); + ++ctx->text.lt.lines; + } + else + ++lt; + if (position == end) + ++position; + else + position = end; + + if (line > ctx->text.lt.lines) { + if (update_from >= 0) + _XawTextNeedsUpdating(ctx, update_from, + ctx->text.lt.info[ctx->text.lt.lines].position); + _XawTextSetScrollBars(ctx); + + return (position); + } + } + /*NOTREACHED*/ +} + +/* + * Function: + * GetWidestLine + * + * Parameters: + * ctx - text widget + * + * Description: + * Returns the width (in pixels) of the widest line that + * is currently visable. + * + * Returns: + * The width of the widest line + */ +static unsigned int +GetWidestLine(TextWidget ctx) +{ + int i; + unsigned int widest; + XawTextLineTablePtr lt = &(ctx->text.lt); + + for (i = 0, widest = 0; i < lt->lines; i++) + if (widest < lt->info[i].textWidth) + widest = lt->info[i].textWidth; + + return (widest); +} + +/* + * This routine is used by Text to notify an associated scrollbar of the + * correct metrics (position and shown fraction) for the text being currently + * displayed in the window. + */ +void +_XawTextSetScrollBars(TextWidget ctx) +{ + float first, last, denom, widest; + + if (ctx->text.scroll_vert == XawtextScrollAlways) { + if (ctx->text.lastPos == 0) + first = 0.0; + else + first = ctx->text.lt.top / (float)ctx->text.lastPos; + + if (ctx->text.lt.info[ctx->text.lt.lines].position < ctx->text.lastPos) + last = ctx->text.lt.info[ctx->text.lt.lines].position / + (float)ctx->text.lastPos; + else + last = 1.0; + + XawScrollbarSetThumb(ctx->text.vbar, first, last - first); + } + + if (ctx->text.scroll_horiz == XawtextScrollAlways) { + denom = GetWidestLine(ctx); + if (denom <= 0) + denom = (int)XtWidth(ctx) - RHMargins(ctx); + if (denom <= 0) + denom = 1; + widest = ((int)XtWidth(ctx) - RHMargins(ctx)) / denom; + first = ctx->text.r_margin.left - ctx->text.left_margin; + first /= denom; + + XawScrollbarSetThumb(ctx->text.hbar, first, widest); + } +} + +static void +DoCopyArea(TextWidget ctx, int src_x, int src_y, + unsigned int width, unsigned int height, int dst_x, int dst_y) +{ + int x1, y1, x2, y2; + + x1 = ctx->text.r_margin.left; + y1 = ctx->text.r_margin.top; + x2 = XtWidth(ctx) - ctx->text.r_margin.right; + y2 = XtHeight(ctx) - ctx->text.r_margin.bottom; + + if (x1 >= x2 || y1 >= y2) + return; + + src_x = XawMax(x1, XawMin(src_x, x2)); + src_y = XawMax(y1, XawMin(src_y, y2)); + dst_x = XawMax(x1, XawMin(dst_x, x2)); + dst_y = XawMax(y1, XawMin(dst_y, y2)); + width = XawMax(0, XawMin(x2 - dst_x, (int)width)); + height = XawMax(0, XawMin(y2 - dst_y, (int)height)); + + XCopyArea(XtDisplay(ctx), XtWindow(ctx), XtWindow(ctx), ctx->text.gc, + src_x, src_y, width, height, dst_x, dst_y); +} + +/* + * Function: + * XawTextScroll + * + * Parameters: + * ctx - text widget + * vlines - number of lines to scroll vertically + * hpixels - number of pixels to scroll horizontally + * + * Description: + * Generic function for scrolling the text window. + * Allows vertical and horizontal scroll at the same time. + */ +void +XawTextScroll(TextWidget ctx, int vlines, int hpixels) +{ + XawTextPosition top, tmp, update_from, update_to; + XawTextLineTable *lt; + Arg arglist[1]; + int y0, y1, y2, count, dim, wwidth, lines = ctx->text.lt.lines; + int vwidth, vheight; /* visible width and height */ + Bool scroll; + + vwidth = (int)XtWidth(ctx) - RHMargins(ctx); + vheight = (int)XtHeight(ctx) - RVMargins(ctx); + lt = &ctx->text.lt; + + if (!lt || vwidth <= 0 || vheight <= 0) + return; + + if ((scroll = ctx->core.background_pixmap == XtUnspecifiedPixmap) == True) { + dim = lt->info[1].y - lt->info[0].y; + for (count = 1; count < lt->lines - 1; count++) + if (lt->info[count + 1].y - lt->info[count].y != dim) { + scroll = False; + break; + } + } + + wwidth = GetMaxTextWidth(ctx); + + /* + * Do the horizontall scrolling + */ + if (hpixels < 0 && ctx->text.left_margin - hpixels > ctx->text.r_margin.left) + hpixels = ctx->text.left_margin - ctx->text.r_margin.left; + ctx->text.left_margin -= hpixels; + + update_from = lt->top; /* remember the old value */ + /* + * Checks the requested number of lines and calculates the top + * of the line table + */ + if (vlines < 0) { /* VScroll Up */ + if (IsPositionVisible(ctx, 0)) + vlines = 0; + else if (ctx->text.wrap != XawtextWrapNever) { + XawTextPosition end; + int n_lines = 0; + + count = -vlines; + end = lt->top; + while (n_lines < count) { + top = SrcScan(ctx->text.source, end, XawstEOL, + XawsdLeft, 2, False); + n_lines += CountLines(ctx, top, end); + end = top; + } + + while (count++ < n_lines) { + tmp = top; + XawTextSinkFindPosition(ctx->text.sink, top, + ctx->text.left_margin, + wwidth,ctx->text.wrap == XawtextWrapWord, + &top, &dim, &dim); + if (tmp == top) + ++top; + } + } + else + top = SrcScan(ctx->text.source, lt->top, XawstEOL, + XawsdLeft, -vlines + 1, False); + if (-vlines >= ctx->text.lt.lines) + scroll = False; + } + else if (vlines > 0) { /* VScroll Down */ + if (LineForPosition(ctx, ctx->text.lastPos) == 0) + vlines = 0; + if (vlines < lt->lines) + top = XawMin(lt->info[vlines].position, ctx->text.lastPos); + else if (ctx->text.wrap == XawtextWrapNever) + top = SrcScan(ctx->text.source, + SrcScan(ctx->text.source, lt->top, + XawstEOL, XawsdRight, vlines, + True), + XawstEOL, XawsdLeft, 1, False); + else { + top = lt->top; + count = 0; + while (count++ < vlines) { + tmp = top; + XawTextSinkFindPosition(ctx->text.sink, top, + ctx->text.left_margin, + wwidth, ctx->text.wrap == XawtextWrapWord, + &top, &dim, &dim); + if (tmp == top) + ++top; + } + } + if (vlines >= ctx->text.lt.lines + || lt->info[vlines].position >= ctx->text.lastPos) + scroll = False; + } + + if (!vlines) { + if (hpixels) { + ClearWindow(ctx); + ctx->text.clear_to_eol = True; + } + _XawTextSetScrollBars(ctx); + return; + } + + /* Flushes any pending updates. Normally, there may be a call to + * XawTextUnsetSelection not yet updated. + */ + if (!hpixels && scroll) { + ctx->text.clear_to_eol = True; + FlushUpdate(ctx); + } + + /* + * Rebuild the line table, doing the vertical scroll + */ + (void)_BuildLineTable(ctx, top, 0); + lt = &ctx->text.lt; + if (scroll) { + for (count = 0; count < lt->lines - 1; count++) + if (lt->info[count + 1].y - lt->info[count].y != dim) { + scroll = False; + break; + } + } + + XtSetArg(arglist[0], XtNinsertPosition, lt->top + lt->lines); + _XawImSetValues((Widget)ctx, arglist, 1); + + if (hpixels || !scroll || lines != lt->lines) + return; + + /* _BuildLineTable updates everything if the top position changes. + * It is not required here. + */ + (void)XmuScanlineXor(ctx->text.update, ctx->text.update); + if (vlines < 0 && IsPositionVisible(ctx, 0)) + vlines = -LineForPosition(ctx, update_from); + + y0 = ctx->text.r_margin.top; + if (vlines < 0) { + update_from = lt->top; + update_to = lt->info[-vlines + 1].position - 1; + y1 = lt->info[lt->lines + vlines].y; + y2 = lt->info[-vlines].y; + DoCopyArea(ctx, ctx->text.r_margin.left, y0, vwidth, + y1 - y0, + ctx->text.r_margin.left, y2); + } + else { + update_from = lt->info[lt->lines - vlines].position; + update_to = lt->info[lt->lines].position; + y1 = lt->info[lt->lines - vlines].y; + y2 = lt->info[vlines].y; + DoCopyArea(ctx, ctx->text.r_margin.left, y2, + vwidth, lt->info[lt->lines].y - y2, + ctx->text.r_margin.left, y0); + } + _XawTextNeedsUpdating(ctx, update_from, update_to); + ctx->text.clear_to_eol = True; +} + +/* + * The routine will scroll the displayed text by lines. If the arg is + * positive, move up; otherwise, move down. [note: this is really a private + * procedure but is used in multiple modules]. + */ +void +_XawTextVScroll(TextWidget ctx, int n) +{ + XawTextScroll(ctx, n, 0); +} + +/*ARGSUSED*/ +static void +HScroll(Widget w, XtPointer closure, XtPointer callData) +{ + TextWidget ctx = (TextWidget)closure; + long pixels = (long)callData; + + if (pixels > 0) { + long max; + + max = (int)GetWidestLine(ctx) + ctx->text.left_margin - + ctx->text.r_margin.left; + max = XawMax(0, max); + pixels = XawMin(pixels, max); + } + + if (pixels) { + _XawTextPrepareToUpdate(ctx); + XawTextScroll(ctx, 0, pixels); + _XawTextExecuteUpdate(ctx); + } +} + +/*ARGSUSED*/ +static void +HJump(Widget w, XtPointer closure, XtPointer callData) +{ + TextWidget ctx = (TextWidget)closure; + float percent = *(float *)callData; + long pixels; + + pixels = ctx->text.left_margin - + (ctx->text.r_margin.left - (int)(percent * GetWidestLine(ctx))); + + HScroll(w, (XtPointer)ctx, (XtPointer)pixels); +} + +/* + * Function: + * UpdateTextInLine + * + * Parameters: + * ctx - text widget + * line - line to update + * x1 - left pixel + * x2 - right pixel + * + * Description: + * Updates the text in the given line and pixel interval + */ +static void +UpdateTextInLine(TextWidget ctx, int line, int x1, int x2) +{ + XawTextLineTableEntry *lt = ctx->text.lt.info + line; + XawTextPosition left, right; + int from_x, width, height; + + if (lt->position >= ctx->text.lastPos + || ctx->text.left_margin > x2 + || (int)lt->textWidth + ctx->text.left_margin < x1) { + /* Mark line to be cleared */ + if (ctx->text.clear_to_eol) + _XawTextNeedsUpdating(ctx, lt->position, lt->position + 1); + return; + } + + from_x = ctx->text.left_margin; + XawTextSinkFindPosition(ctx->text.sink, lt->position, + from_x, x1 - from_x, + False, &left, &width, &height); + if (line == ctx->text.lt.lines) + right = -1; + else if (x2 >= lt->textWidth - from_x) + right = lt[1].position - 1; + else { + from_x += width; + XawTextSinkFindPosition(ctx->text.sink, left, + from_x, x2 - from_x, + False, &right, &width, &height); + } + + if ((right < 0) || (right + 1 <= lt[1].position)) + ++right; + + /* Mark text interval to be repainted */ + _XawTextNeedsUpdating(ctx, left, right); +} + +/* + * The routine will scroll the displayed text by pixels. If the calldata is + * positive, move up; otherwise, move down. + */ +/*ARGSUSED*/ +static void +VScroll(Widget w, XtPointer closure, XtPointer callData) +{ + TextWidget ctx = (TextWidget)closure; + long height, lines = (long)callData; + + height = XtHeight(ctx) - VMargins(ctx); + if (height < 1) + height = 1; + lines = (lines * ctx->text.lt.lines) / height; + _XawTextPrepareToUpdate(ctx); + XawTextScroll(ctx, lines, 0); + _XawTextExecuteUpdate(ctx); +} + +/*ARGSUSED*/ +static void +VJump(Widget w, XtPointer closure, XtPointer callData) +{ + float percent = *(float *)callData; + TextWidget ctx = (TextWidget)closure; + XawTextPosition top, last, position, tmp; + XawTextLineTable *lt = &(ctx->text.lt); + int dim, vlines = 0, wwidth = GetMaxTextWidth(ctx); + Bool scroll = True; + + position = percent * ctx->text.lastPos; + top = lt->top; + + if (!lt->lines || (position >= lt->top && position < lt->info[1].position)) { + _XawTextSetScrollBars(ctx); + return; + } + +#ifndef OLDXAW + ctx->text.lt.base_line = -1; +#endif + + if (position > lt->top) { /* VScroll Up */ + if (position > lt->top && position < lt->info[lt->lines].position) + vlines = LineForPosition(ctx, position); + else { + scroll = False; + top = SrcScan(ctx->text.source, position, XawstEOL, + XawsdLeft, 1, False); + if (ctx->text.wrap != XawtextWrapNever) { + last = top; + while (last < position) { + tmp = last; + XawTextSinkFindPosition(ctx->text.sink, last, + ctx->text.left_margin, wwidth, + ctx->text.wrap == XawtextWrapWord, + &last, &dim, &dim); + if (last == tmp) + ++last; + if (last < position) + top = last; + } + } + } + } + else { /* VScroll Down */ + /* + * Calculates the number of lines + */ + while (top > position) { + last = top; + top = SrcScan(ctx->text.source, top, XawstEOL, + XawsdLeft, 2, False); + vlines -= CountLines(ctx, top, last); + if (-vlines >= ctx->text.lt.lines) { + scroll = False; + top = SrcScan(ctx->text.source, position, XawstEOL, + XawsdLeft, 1, False); + break; + } + } + /* + * Normalize + */ + if (ctx->text.wrap != XawtextWrapNever) { + last = top; + while (last < position) { + tmp = last; + XawTextSinkFindPosition(ctx->text.sink, last, + ctx->text.left_margin, + wwidth, + ctx->text.wrap == XawtextWrapWord, + &last, &dim, &dim); + if (last == tmp) + ++last; + if (last < position) + top = last; + ++vlines; + } + } + } + + if (vlines || !scroll) { + _XawTextPrepareToUpdate(ctx); + if (scroll) + XawTextScroll(ctx, vlines, 0); + else + _BuildLineTable(ctx, top, 0); + _XawTextExecuteUpdate(ctx); + } +} + +static Bool +MatchSelection(Atom selection, XawTextSelection *s) +{ + Atom *match; + int count; + + for (count = 0, match = s->selections; count < s->atom_count; + match++, count++) + if (*match == selection) + return (True); + + return (False); +} + +static Boolean +TextConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type, + XtPointer *value, unsigned long *length, int *format) +{ + Display *d = XtDisplay(w); + TextWidget ctx = (TextWidget)w; + Widget src = ctx->text.source; + XawTextEditType edit_mode; + Arg args[1]; + XawTextSelectionSalt *salt = NULL; + XawTextSelection *s; + + if (*target == XA_TARGETS(d)) { + Atom *targetP, *std_targets; + unsigned long std_length; + + if (SrcCvtSel(src, selection, target, type, value, length, format)) + return (True); + + XtSetArg(args[0], XtNeditType, &edit_mode); + XtGetValues(src, args, ONE); + + XmuConvertStandardSelection(w, ctx->text.time, selection, + target, type, (XPointer*)&std_targets, + &std_length, format); + + *length = 7 + (edit_mode == XawtextEdit) + std_length; + *value = XtMalloc((unsigned)sizeof(Atom)*(*length)); + targetP = *(Atom**)value; + *targetP++ = XA_STRING; + *targetP++ = XA_TEXT(d); + *targetP++ = XA_UTF8_STRING(d); + *targetP++ = XA_COMPOUND_TEXT(d); + *targetP++ = XA_LENGTH(d); + *targetP++ = XA_LIST_LENGTH(d); + *targetP++ = XA_CHARACTER_POSITION(d); + if (edit_mode == XawtextEdit) { + *targetP++ = XA_DELETE(d); + } + (void)memmove((char*)targetP, (char*)std_targets, + sizeof(Atom) * std_length); + XtFree((char*)std_targets); + *type = XA_ATOM; + *format = 32; + return (True); + } + + if (SrcCvtSel(src, selection, target, type, value, length, format)) + return (True); + + if (MatchSelection(*selection, &ctx->text.s)) + s = &ctx->text.s; + else { + for (salt = ctx->text.salt; salt; salt = salt->next) + if (MatchSelection(*selection, &salt->s)) + break; + if (!salt) + return (False); + s = &salt->s; + } + if (*target == XA_STRING + || *target == XA_TEXT(d) + || *target == XA_UTF8_STRING(d) + || *target == XA_COMPOUND_TEXT(d)) { + if (*target == XA_TEXT(d)) { + if (XawTextFormat(ctx, XawFmtWide)) + *type = XA_COMPOUND_TEXT(d); + else + *type = XA_STRING; + } + else + *type = *target; + /* + * If salt is True, the salt->contents stores CT string, + * its length is measured in bytes. + * Refer to _XawTextSaltAwaySelection(). + * + * by Li Yuhong, Mar. 20, 1991. + */ + if (!salt) { + *value = _XawTextGetSTRING(ctx, s->left, s->right); + if (XawTextFormat(ctx, XawFmtWide)) { + XTextProperty textprop; + if (XwcTextListToTextProperty(d, (wchar_t **)value, 1, + XCompoundTextStyle, &textprop) + < Success) { + XtFree((char *)*value); + return (False); + } + XtFree((char *)*value); + *value = (XtPointer)textprop.value; + *length = textprop.nitems; + } + else + *length = strlen((char *)*value); + } + else { + *value = XtMalloc((salt->length + 1) * sizeof(unsigned char)); + strcpy ((char *)*value, salt->contents); + *length = salt->length; + } + /* Got *value,*length, now in COMPOUND_TEXT format. */ + if (XawTextFormat(ctx, XawFmtWide) && *type == XA_STRING) { + XTextProperty textprop; + wchar_t **wlist; + int count; + + textprop.encoding = XA_COMPOUND_TEXT(d); + textprop.value = (unsigned char *)*value; + textprop.nitems = strlen(*value); + textprop.format = 8; + if (XwcTextPropertyToTextList(d, &textprop, &wlist, &count) + < Success + || count < 1) { + XtFree((char *)*value); + return (False); + } + XtFree((char *)*value); + if (XwcTextListToTextProperty(d, wlist, 1, XStringStyle, &textprop) + < Success) { + XwcFreeStringList((wchar_t**) wlist); + return (False); + } + *value = (XtPointer)textprop.value; + *length = textprop.nitems; + XwcFreeStringList(wlist); + } else if (*type == XA_UTF8_STRING(d)) { + XTextProperty textprop; + char **list; + int count; + + textprop.encoding = XA_COMPOUND_TEXT(d); + textprop.value = (unsigned char *)*value; + textprop.nitems = strlen(*value); + textprop.format = 8; + if (Xutf8TextPropertyToTextList(d, &textprop, &list, &count) + < Success + || count < 1) { + XtFree((char *)*value); + return (False); + } + XtFree((char *)*value); + *value = *list; + *length = strlen(*list); + XFree(list); + } + *format = 8; + return (True); + } + + if ((*target == XA_LIST_LENGTH(d)) || (*target == XA_LENGTH(d))) { + long * temp; + + temp = (long *)XtMalloc((unsigned)sizeof(long)); + if (*target == XA_LIST_LENGTH(d)) + *temp = 1L; + else /* *target == XA_LENGTH(d) */ + *temp = (long) (s->right - s->left); + + *value = (XPointer)temp; + *type = XA_INTEGER; + *length = 1L; + *format = 32; + return (True); + } + + if (*target == XA_CHARACTER_POSITION(d)) { + long * temp; + + temp = (long *)XtMalloc((unsigned)(2 * sizeof(long))); + temp[0] = (long)(s->left + 1); + temp[1] = s->right; + *value = (XPointer)temp; + *type = XA_SPAN(d); + *length = 2L; + *format = 32; + return (True); + } + + if (*target == XA_DELETE(d)) { + if (!salt) + _XawTextZapSelection(ctx, NULL, True); + *value = NULL; + *type = XA_NULL(d); + *length = 0; + *format = 32; + return (True); + } + + if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type, + (XPointer *)value, length, format)) + return (True); + + /* else */ + return (False); +} + +/* + * Function: + * GetCutBuffferNumber + * + * Parameters: + * atom - atom to check + * + * Description: + * Returns the number of the cut buffer. + * + * Returns: + * The number of the cut buffer representing this atom or NOT_A_CUT_BUFFER + */ +#define NOT_A_CUT_BUFFER -1 +static int +GetCutBufferNumber(Atom atom) +{ + if (atom == XA_CUT_BUFFER0) return (0); + if (atom == XA_CUT_BUFFER1) return (1); + if (atom == XA_CUT_BUFFER2) return (2); + if (atom == XA_CUT_BUFFER3) return (3); + if (atom == XA_CUT_BUFFER4) return (4); + if (atom == XA_CUT_BUFFER5) return (5); + if (atom == XA_CUT_BUFFER6) return (6); + if (atom == XA_CUT_BUFFER7) return (7); + return (NOT_A_CUT_BUFFER); +} + +static void +TextLoseSelection(Widget w, Atom *selection) +{ + TextWidget ctx = (TextWidget)w; + Atom *atomP; + int i; + XawTextSelectionSalt*salt, *prevSalt, *nextSalt; + + atomP = ctx->text.s.selections; + for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++) + if ((*selection == *atomP) + || (GetCutBufferNumber(*atomP) != NOT_A_CUT_BUFFER)) + *atomP = (Atom)0; + + while (ctx->text.s.atom_count + && ctx->text.s.selections[ctx->text.s.atom_count - 1] == 0) + ctx->text.s.atom_count--; + + /* + * Must walk the selection list in opposite order from UnsetSelection + */ + atomP = ctx->text.s.selections; + for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++) + if (*atomP == (Atom)0) { + *atomP = ctx->text.s.selections[--ctx->text.s.atom_count]; + while (ctx->text.s.atom_count + && ctx->text.s.selections[ctx->text.s.atom_count-1] == 0) + ctx->text.s.atom_count--; + } + + if (ctx->text.s.atom_count == 0) + ModifySelection(ctx, ctx->text.insertPos, ctx->text.insertPos); + + prevSalt = 0; + for (salt = ctx->text.salt; salt; salt = nextSalt) { + atomP = salt->s.selections; + nextSalt = salt->next; + for (i = 0 ; i < salt->s.atom_count; i++, atomP++) + if (*selection == *atomP) + *atomP = (Atom)0; + + while (salt->s.atom_count + && salt->s.selections[salt->s.atom_count-1] == 0) + salt->s.atom_count--; + + /* + * Must walk the selection list in opposite order from UnsetSelection + */ + atomP = salt->s.selections; + for (i = 0 ; i < salt->s.atom_count; i++, atomP++) + if (*atomP == (Atom)0) { + *atomP = salt->s.selections[--salt->s.atom_count]; + while (salt->s.atom_count + && salt->s.selections[salt->s.atom_count-1] == 0) + salt->s.atom_count--; + } + + if (salt->s.atom_count == 0) { + XtFree ((char *) salt->s.selections); + XtFree (salt->contents); + if (prevSalt) + prevSalt->next = nextSalt; + else + ctx->text.salt = nextSalt; + XtFree((char *)salt); + } + else + prevSalt = salt; + } +} + +void +_XawTextSaltAwaySelection(TextWidget ctx, Atom *selections, int num_atoms) +{ + XawTextSelectionSalt *salt; + int i, j; + + for (i = 0; i < num_atoms; i++) + TextLoseSelection((Widget)ctx, selections + i); + if (num_atoms == 0) + return; + salt = (XawTextSelectionSalt *) + XtMalloc((unsigned)sizeof(XawTextSelectionSalt)); + if (!salt) + return; + salt->s.selections = (Atom *)XtMalloc((unsigned)(num_atoms * sizeof(Atom))); + if (!salt->s.selections) { + XtFree((char *)salt); + return; + } + salt->s.left = ctx->text.s.left; + salt->s.right = ctx->text.s.right; + salt->s.type = ctx->text.s.type; + salt->contents = _XawTextGetSTRING(ctx, ctx->text.s.left, ctx->text.s.right); + if (XawTextFormat(ctx, XawFmtWide)) { + XTextProperty textprop; + if (XwcTextListToTextProperty(XtDisplay((Widget)ctx), + (wchar_t**)(&(salt->contents)), 1, + XCompoundTextStyle, + &textprop) < Success) { + XtFree(salt->contents); + salt->length = 0; + return; + } + XtFree(salt->contents); + salt->contents = (char *)textprop.value; + salt->length = textprop.nitems; + } + else + salt->length = strlen (salt->contents); + salt->next = ctx->text.salt; + ctx->text.salt = salt; + j = 0; + for (i = 0; i < num_atoms; i++) { + if (GetCutBufferNumber (selections[i]) == NOT_A_CUT_BUFFER) { + salt->s.selections[j++] = selections[i]; + XtOwnSelection((Widget)ctx, selections[i], ctx->text.time, + TextConvertSelection, TextLoseSelection, NULL); + } + } + salt->s.atom_count = j; +} + +static void +_SetSelection(TextWidget ctx, XawTextPosition left, XawTextPosition right, + Atom *selections, Cardinal count) +{ +#ifndef OLDXAW + Cardinal i; + XawTextPosition pos; + TextSrcObject src = (TextSrcObject)ctx->text.source; + + for (i = 0; i < src->textSrc.num_text; i++) { + TextWidget tw = (TextWidget)src->textSrc.text[i]; + Bool needs_updating = tw->text.old_insert < 0; + Bool showposition = tw->text.showposition; + + if (needs_updating) { + tw->text.showposition = False; + _XawTextPrepareToUpdate(tw); + } +#else + TextWidget tw = ctx; + XawTextPosition pos; +#endif /* OLDXAW */ + + if (left < tw->text.s.left) { + pos = Min(right, tw->text.s.left); + _XawTextNeedsUpdating(tw, left, pos); + } + if (left > tw->text.s.left) { + pos = Min(left, tw->text.s.right); + _XawTextNeedsUpdating(tw, tw->text.s.left, pos); + } + if (right < tw->text.s.right) { + pos = Max(right, tw->text.s.left); + _XawTextNeedsUpdating(tw, pos, tw->text.s.right); + } + if (right > tw->text.s.right) { + pos = Max(left, tw->text.s.right); + _XawTextNeedsUpdating(tw, pos, right); + } + + tw->text.s.left = left; + tw->text.s.right = right; + +#ifndef OLDXAW + if (needs_updating) { + _XawTextExecuteUpdate(tw); + tw->text.showposition = showposition; + } + } +#endif /* OLDXAW */ + + SrcSetSelection(ctx->text.source, left, right, + (count == 0) ? None : selections[0]); + + if (left < right) { + Widget w = (Widget)ctx; + int buffer; + + while (count) { + Atom selection = selections[--count]; + + /* + * If this is a cut buffer + */ + if ((buffer = GetCutBufferNumber(selection)) != NOT_A_CUT_BUFFER) { + unsigned char *ptr, *tptr; + unsigned int amount, max_len = MAX_CUT_LEN(XtDisplay(w)); + unsigned long len; + + tptr= ptr= (unsigned char *)_XawTextGetSTRING(ctx, + ctx->text.s.left, + ctx->text.s.right); + if (XawTextFormat(ctx, XawFmtWide)) { + /* + * Only XA_STRING(Latin 1) is allowed in CUT_BUFFER, + * so we get it from wchar string, then free the wchar string + */ + XTextProperty textprop; + + if (XwcTextListToTextProperty(XtDisplay(w), (wchar_t**)&ptr, + 1, XStringStyle, &textprop) + < Success){ + XtFree((char *)ptr); + return; + } + XtFree((char *)ptr); + tptr = ptr = textprop.value; + } + if (buffer == 0) { + _CreateCutBuffers(XtDisplay(w)); + XRotateBuffers(XtDisplay(w), 1); + } + amount = Min ((len = strlen((char *)ptr)), max_len); + XChangeProperty(XtDisplay(w), RootWindow(XtDisplay(w), 0), + selection, XA_STRING, 8, PropModeReplace, + ptr, amount); + + while (len > max_len) { + len -= max_len; + tptr += max_len; + amount = Min (len, max_len); + XChangeProperty(XtDisplay(w), RootWindow(XtDisplay(w), 0), + selection, XA_STRING, 8, PropModeAppend, + tptr, amount); + } + XtFree ((char *)ptr); + } + else /* This is a real selection */ + XtOwnSelection(w, selection, ctx->text.time, TextConvertSelection, + TextLoseSelection, NULL); + } + } + else + XawTextUnsetSelection((Widget)ctx); +} + +#ifndef OLDXAW +void +_XawTextSetLineAndColumnNumber(TextWidget ctx, Bool force) +{ + int line_number, column_number; + + if (ctx->text.old_insert != ctx->text.insertPos && + ctx->text.lt.base_line < 0) { + ctx->text.lt.base_line = 0; + (void)_BuildLineTable(ctx, ctx->text.lt.top, 0); + } + + line_number = ResolveLineNumber(ctx); + column_number = ResolveColumnNumber(ctx); + + if (force || (ctx->text.column_number != column_number + || ctx->text.line_number != line_number)) { + XawTextPositionInfo info; + + ctx->text.line_number = info.line_number = line_number; + ctx->text.column_number = info.column_number = column_number; + info.insert_position = ctx->text.insertPos; + info.last_position = ctx->text.lastPos; + info.overwrite_mode = ctx->text.overwrite; + + XtCallCallbacks((Widget)ctx, XtNpositionCallback, (XtPointer)&info); + } +} + +static int +ResolveColumnNumber(TextWidget ctx) +{ + Widget src = ctx->text.source; + short column_number = 0; + XawTextPosition position; + XawTextBlock block; + unsigned long format = _XawTextFormat(ctx); + TextSinkObject sink = (TextSinkObject)ctx->text.sink; + short *char_tabs = sink->text_sink.char_tabs; + int tab_count = sink->text_sink.tab_count; + int tab_index = 0, tab_column = 0, tab_base = 0; + + if (ctx->text.lt.base_line < 1) + return (ctx->text.column_number); + + position = SrcScan(src, ctx->text.insertPos, XawstEOL, XawsdLeft, 1, False); + XawTextSourceRead(src, position, &block, ctx->text.insertPos - position); + + for (; position < ctx->text.insertPos; position++) { + if (position - block.firstPos >= block.length) + XawTextSourceRead(src, position, &block, ctx->text.insertPos - position); + if ((format == XawFmt8Bit && block.ptr[position - block.firstPos] == '\t') || + (format == XawFmtWide && ((wchar_t*)block.ptr)[position - block.firstPos] == _Xaw_atowc(XawTAB))) { + while (tab_base + tab_column <= column_number) { + if (tab_count) { + for (; tab_index < tab_count; ++tab_index) + if (tab_base + char_tabs[tab_index] > column_number) { + tab_column = char_tabs[tab_index]; + break; + } + if (tab_index >= tab_count) { + tab_base += char_tabs[tab_count - 1]; + tab_column = tab_index = 0; + } + } + else + tab_column += DEFAULT_TAB_SIZE; + } + column_number = tab_base + tab_column; + } + else + ++column_number; + if (column_number >= 16384) { + column_number = 16383; + break; + } + } + + return (column_number); +} +#endif /* OLDXAW */ + +void +_XawTextSourceChanged(Widget w, XawTextPosition left, XawTextPosition right, + XawTextBlock *block, int lines) +{ + TextWidget ctx = (TextWidget)w; + Widget src = ctx->text.source; + XawTextPosition update_from, update_to, top; + Boolean update_disabled; + int delta, line, line_from; + + if (left < ctx->text.old_insert) { + XawTextPosition old_insert = ctx->text.old_insert; + + if (right < ctx->text.old_insert) + old_insert -= right - left; + else + old_insert = left; + + ctx->text.insertPos = old_insert + block->length; + } +#ifndef OLDXAW + if (left <= ctx->text.lt.top) { + if (left + block->length - (right - left) < ctx->text.lt.top) { + ctx->text.source_changed = SRC_CHANGE_BEFORE; + ctx->text.lt.base_line += lines; + } + else + ctx->text.source_changed = SRC_CHANGE_OVERLAP; + } + else + ctx->text.source_changed = SRC_CHANGE_AFTER; +#endif + + update_from = left; + update_to = left + block->length; + update_to = SrcScan(src, update_to, XawstEOL, XawsdRight, 1, False); + delta = block->length - (right - left); + if (delta < 0) + ctx->text.clear_to_eol = True; + if (update_to == update_from) + ++update_to; + update_disabled = ctx->text.update_disabled; + ctx->text.update_disabled = True; + ctx->text.lastPos = XawTextGetLastPosition(ctx); + top = ctx->text.lt.info[0].position; + + XawTextUnsetSelection((Widget)ctx); + + if (delta) { + int i; + XmuSegment *seg; + + for (seg = ctx->text.update->segment; seg; seg = seg->next) { + if (seg->x1 > (int)left) + break; + else if (seg->x2 > (int)left) { + seg->x2 += delta; + seg = seg->next; + break; + } + } + for (; seg; seg = seg->next) { + seg->x1 += delta; + seg->x2 += delta; + } + XmuOptimizeScanline(ctx->text.update); + + for (i = 0; i <= ctx->text.lt.lines; i++) + if (ctx->text.lt.info[i].position > left) + break; + for (; i <= ctx->text.lt.lines; i++) + ctx->text.lt.info[i].position += delta; + } + + if (top != ctx->text.lt.info[0].position) { + line_from = line = 0; + ctx->text.lt.top = top = SrcScan(src, ctx->text.lt.info[0].position, + XawstEOL, XawsdLeft, 1, False); + update_from = top; + } + else { + line_from = line = LineForPosition(ctx, update_from + delta); + top = ctx->text.lt.info[line].position; + } + + if (line > 0 && ctx->text.wrap == XawtextWrapWord) { + --line; + top = ctx->text.lt.info[line].position; + } + + (void)_BuildLineTable(ctx, top, line); + + if (ctx->text.wrap == XawtextWrapWord) { + if (line_from != LineForPosition(ctx, update_from) + || line_from != LineForPosition(ctx, update_to)) { + ctx->text.clear_to_eol = True; + update_from = SrcScan(src, update_from, + XawstWhiteSpace, XawsdLeft, 1, True); + if (update_to >= ctx->text.lastPos) + /* this is not an error, it just tells _BuildLineTable to + * clear to the bottom of the window. The value of update_to + * should not be > ctx->text.lastPos. + */ + ++update_to; + } + } + else if (!ctx->text.clear_to_eol) { + if (LineForPosition(ctx, update_from) + != LineForPosition(ctx, update_to)) + ctx->text.clear_to_eol = True; + } + + _XawTextNeedsUpdating(ctx, update_from, update_to); + ctx->text.update_disabled = update_disabled; +} + +/* + * Function: + * _XawTextReplace + * + * Parameters: + * ctx - text widget + * left - left offset + * right - right offset + * block - text block + * + * Description: + * Replaces the text between left and right by the text in block. + * Does all the required calculations of offsets, and rebuild the + * the line table, from the insertion point (or previous line, if + * wrap mode is 'word'). + * + * Returns: + * XawEditDone - success + * any other value - error code + */ +int +_XawTextReplace(TextWidget ctx, XawTextPosition left, XawTextPosition right, + XawTextBlock *block) +{ + Arg args[1]; + Widget src; + XawTextEditType edit_mode; + + if (left == right && block->length == 0) + return (XawEditDone); + + src = ctx->text.source; + XtSetArg(args[0], XtNeditType, &edit_mode); + XtGetValues(src, args, 1); + + if (edit_mode == XawtextAppend) { + if (block->length == 0) + return (XawEditError); + ctx->text.insertPos = ctx->text.lastPos; + } + +#ifndef OLDXAW + return (SrcReplace(src, left, right, block)); +#else + if (SrcReplace(src, left, right, block) == XawEditDone) { + _XawTextSourceChanged((Widget)ctx, left, right, block, 0); + + return (XawEditDone); + } + + return (XawEditError); +#endif +} + +/* + * This routine will display text between two arbitrary source positions. + * In the event that this span contains highlighted text for the selection, + * only that portion will be displayed highlighted. + */ +static void +OldDisplayText(Widget w, XawTextPosition left, XawTextPosition right) +{ + static XmuSegment segment; + static XmuScanline next; + static XmuScanline scanline = {0, &segment, &next}; + static XmuArea area = {&scanline}; + + TextWidget ctx = (TextWidget)w; + int x, y, line; + XawTextPosition start, end, last, final; + XmuScanline *scan; + XmuSegment *seg; + XmuArea *clip = NULL; + Bool cleol = ctx->text.clear_to_eol; + Bool has_selection = ctx->text.s.right > ctx->text.s.left; + + left = left < ctx->text.lt.top ? ctx->text.lt.top : left; + + if (left > right || !LineAndXYForPosition(ctx, left, &line, &x, &y)) + return; + + last = XawTextGetLastPosition(ctx); + segment.x2 = (int)XtWidth(ctx) - ctx->text.r_margin.right; + + if (cleol) + clip = XmuCreateArea(); + + for (start = left; start < right && line < ctx->text.lt.lines; line++) { + if ((end = ctx->text.lt.info[line + 1].position) > right) + end = right; + + final = end; + if (end > last) + end = last; + + if (end > start) { + if (!has_selection + || (start >= ctx->text.s.right || end <= ctx->text.s.left)) + _XawTextSinkDisplayText(ctx->text.sink, x, y, start, end, False); + else if (start >= ctx->text.s.left && end <= ctx->text.s.right) + _XawTextSinkDisplayText(ctx->text.sink, x, y, start, end, True); + else { + OldDisplayText(w, start, ctx->text.s.left); + OldDisplayText(w, Max(start, ctx->text.s.left), + Min(end, ctx->text.s.right)); + OldDisplayText(w, ctx->text.s.right, end); + } + } + + x = ctx->text.left_margin; + if (cleol) { + segment.x1 = ctx->text.lt.info[line].textWidth + x; + if (XmuValidSegment(&segment)) { + scanline.y = y; + next.y = ctx->text.lt.info[line + 1].y; + XmuAreaOr(clip, &area); + } + } + + start = final; + y = ctx->text.lt.info[line + 1].y; + } + + if (cleol) { + for (scan = clip->scanline; scan && scan->next; scan = scan->next) + for (seg = scan->segment; seg; seg = seg->next) + SinkClearToBG(ctx->text.sink, + seg->x1, scan->y, + seg->x2 - seg->x1, scan->next->y - scan->y); + XmuDestroyArea(clip); + } +} + +#ifndef OLDXAW +/*ARGSUSED*/ +static void +DisplayText(Widget w, XawTextPosition left, XawTextPosition right) +{ + static XmuSegment segment; + static XmuScanline next; + static XmuScanline scanline = {0, &segment, &next}; + static XmuArea area = {&scanline}; + + TextWidget ctx = (TextWidget)w; + int y, line; + XawTextPosition from, to, lastPos; + Bool cleol = ctx->text.clear_to_eol; + Bool has_selection = ctx->text.s.right > ctx->text.s.left; + XawTextPaintList *paint_list; + + left = left < ctx->text.lt.top ? ctx->text.lt.top : left; + + if (left > right || !IsPositionVisible(ctx, left)) + return; + + line = LineForPosition(ctx, left); + y = ctx->text.lt.info[line].y; + segment.x2 = (int)XtWidth(ctx) - ctx->text.r_margin.right; + lastPos = XawTextGetLastPosition(ctx); + + paint_list = ((TextSinkObject)ctx->text.sink)->text_sink.paint; + + for (from = left; from < right && line < ctx->text.lt.lines; line++) { + if ((to = ctx->text.lt.info[line + 1].position) > right) + to = right; + + if (to > lastPos) + to = lastPos; + + if (from < to) { + if (!has_selection + || (from >= ctx->text.s.right || to <= ctx->text.s.left)) + XawTextSinkPreparePaint(ctx->text.sink, y, line, from, to, False); + else if (from >= ctx->text.s.left && to <= ctx->text.s.right) + XawTextSinkPreparePaint(ctx->text.sink, y, line, from, to, True); + else { + XawTextSinkPreparePaint(ctx->text.sink, y, line, from, + ctx->text.s.left, False); + XawTextSinkPreparePaint(ctx->text.sink, y, line, + XawMax(from, ctx->text.s.left), + XawMin(to, ctx->text.s.right), True); + XawTextSinkPreparePaint(ctx->text.sink, y, line, + ctx->text.s.right, to, False); + } + } + + if (cleol) { + segment.x1 = ctx->text.lt.info[line].textWidth + ctx->text.left_margin; + if (XmuValidSegment(&segment)) { + scanline.y = y; + next.y = ctx->text.lt.info[line + 1].y; + XmuAreaOr(paint_list->clip, &area); + } + } + y = ctx->text.lt.info[line + 1].y; + from = to; + } + + /* clear to the bottom of the window */ + if (cleol && line >= ctx->text.lt.lines) { + segment.x1 = ctx->text.left_margin; + if (XmuValidSegment(&segment)) { + scanline.y = y; + next.y = (int)XtHeight(ctx) - (int)ctx->text.margin.bottom; + XmuAreaOr(paint_list->clip, &area); + } + } +} +#endif + +/* + * This routine implements multi-click selection in a hardwired manner. + * It supports multi-click entity cycling (char, word, line, file) and mouse + * motion adjustment of the selected entitie (i.e. select a word then, with + * button still down, adjust wich word you really meant by moving the mouse). + * [NOTE: This routine is to be replaced by a set of procedures that + * will allows clients to implements a wide class of draw through and + * multi-click selection user interfaces.] + */ +static void +DoSelection(TextWidget ctx, XawTextPosition pos, Time time, Bool motion) +{ + XawTextPosition newLeft, newRight; + XawTextSelectType newType, *sarray; + Widget src = ctx->text.source; + + if (motion) + newType = ctx->text.s.type; + else { + if ((abs((long) time - (long) ctx->text.lasttime) < MULTI_CLICK_TIME) + && (pos >= ctx->text.s.left && pos <= ctx->text.s.right)) { + sarray = ctx->text.sarray; + for (; *sarray != XawselectNull && *sarray != ctx->text.s.type; + sarray++) + ; + if (*sarray == XawselectNull) + newType = *(ctx->text.sarray); + else { + newType = *(sarray + 1); + if (newType == XawselectNull) + newType = *(ctx->text.sarray); + } + } + else /* single-click event */ + newType = *(ctx->text.sarray); + + ctx->text.lasttime = time; + } + switch (newType) { + case XawselectPosition: + newLeft = newRight = pos; + break; + case XawselectChar: + newLeft = pos; + newRight = SrcScan(src, pos, XawstPositions, XawsdRight, 1, False); + break; + case XawselectWord: + case XawselectParagraph: + case XawselectAlphaNumeric: { + XawTextScanType stype; + + if (newType == XawselectWord) + stype = XawstWhiteSpace; + else if (newType == XawselectParagraph) + stype = XawstParagraph; + else + stype = XawstAlphaNumeric; + + /* + * Somewhat complicated, but basically I treat the space between + * two objects as another object. The object that I am currently + * in then becomes the end of the selection. + * + * Chris Peterson - 4/19/90. + */ + newRight = SrcScan(ctx->text.source, pos, stype, + XawsdRight, 1, False); + newRight = SrcScan(ctx->text.source, newRight, stype, + XawsdLeft, 1, False); + + if (pos != newRight) + newLeft = SrcScan(ctx->text.source, pos, stype, + XawsdLeft, 1, False); + else + newLeft = pos; + + newLeft =SrcScan(ctx->text.source, newLeft, stype, + XawsdRight, 1, False); + + if (newLeft > newRight) { + XawTextPosition temp = newLeft; + newLeft = newRight; + newRight = temp; + } + } break; + case XawselectLine: + newLeft = SrcScan(src, pos, XawstEOL, XawsdLeft, 1, False); + newRight = SrcScan(src, pos, XawstEOL, XawsdRight, 1, False); + break; + case XawselectAll: + newLeft = SrcScan(src, pos, XawstAll, XawsdLeft, 1, False); + newRight = SrcScan(src, pos, XawstAll, XawsdRight, 1, False); + break; + default: + XtAppWarning(XtWidgetToApplicationContext((Widget) ctx), + "Text Widget: empty selection array."); + return; + } + + if (newLeft != ctx->text.s.left || newRight != ctx->text.s.right + || newType != ctx->text.s.type) { + ModifySelection(ctx, newLeft, newRight); + if (pos - ctx->text.s.left < ctx->text.s.right - pos) + ctx->text.insertPos = newLeft; + else + ctx->text.insertPos = newRight; + ctx->text.s.type = newType; + } + if (!motion) { /* setup so we can freely mix select extend calls*/ + ctx->text.origSel.type = ctx->text.s.type; + ctx->text.origSel.left = ctx->text.s.left; + ctx->text.origSel.right = ctx->text.s.right; + + if (pos >= ctx->text.s.left + (ctx->text.s.right - ctx->text.s.left) / 2) + ctx->text.extendDir = XawsdRight; + else + ctx->text.extendDir = XawsdLeft; + } +} + +/* + * This routine implements extension of the currently selected text in + * the "current" mode (i.e. char word, line, etc.). It worries about + * extending from either end of the selection and handles the case when you + * cross through the "center" of the current selection (e.g. switch which + * end you are extending!). + */ +static void +ExtendSelection(TextWidget ctx, XawTextPosition pos, Bool motion) +{ + XawTextScanDirection dir; + + if (!motion) { /* setup for extending selection */ + if (ctx->text.s.left == ctx->text.s.right) /* no current selection. */ + ctx->text.s.left = ctx->text.s.right = ctx->text.insertPos; + else { + ctx->text.origSel.left = ctx->text.s.left; + ctx->text.origSel.right = ctx->text.s.right; + } + + ctx->text.origSel.type = ctx->text.s.type; + + if (pos >= ctx->text.s.left + (ctx->text.s.right - ctx->text.s.left) / 2) + ctx->text.extendDir = XawsdRight; + else + ctx->text.extendDir = XawsdLeft; + } + else /* check for change in extend direction */ + if ((ctx->text.extendDir == XawsdRight && + pos <= ctx->text.origSel.left) || + (ctx->text.extendDir == XawsdLeft && + pos >= ctx->text.origSel.right)) { + ctx->text.extendDir = (ctx->text.extendDir == XawsdRight) ? + XawsdLeft : XawsdRight; + ModifySelection(ctx, ctx->text.origSel.left, ctx->text.origSel.right); + } + + dir = ctx->text.extendDir; + switch (ctx->text.s.type) { + case XawselectWord: + case XawselectParagraph: + case XawselectAlphaNumeric: { + XawTextPosition left_pos, right_pos; + XawTextScanType stype; + + if (ctx->text.s.type == XawselectWord) + stype = XawstWhiteSpace; + else if (ctx->text.s.type == XawselectParagraph) + stype = XawstParagraph; + else + stype = XawstAlphaNumeric; + + /* + * Somewhat complicated, but basically I treat the space between + * two objects as another object. The object that I am currently + * in then becomes the end of the selection. + * + * Chris Peterson - 4/19/90. + */ + right_pos = SrcScan(ctx->text.source, pos, stype, + XawsdRight, 1, False); + right_pos =SrcScan(ctx->text.source, right_pos, stype, + XawsdLeft, 1, False); + + if (pos != right_pos) + left_pos = SrcScan(ctx->text.source, pos, stype, + XawsdLeft, 1, False); + else + left_pos = pos; + + left_pos =SrcScan(ctx->text.source, left_pos, stype, + XawsdRight, 1, False); + + if (dir == XawsdLeft) + pos = Min(left_pos, right_pos); + else /* dir == XawsdRight */ + pos = Max(left_pos, right_pos); + } break; + case XawselectLine: + pos = SrcScan(ctx->text.source, pos, XawstEOL, + dir, 1, dir == XawsdRight); + break; + case XawselectAll: + pos = ctx->text.insertPos; + /*FALLTHROUGH*/ + case XawselectPosition: + default: + break; + } + + if (dir == XawsdRight) + ModifySelection(ctx, ctx->text.s.left, pos); + else + ModifySelection(ctx, pos, ctx->text.s.right); + + ctx->text.insertPos = pos; +} + +/* + * Function: + * _XawTextClearAndCenterDisplay + * + * Parameters: + * ctx - text widget + * + * Description: + * Redraws the display with the cursor in insert point + * centered vertically. + */ +void +_XawTextClearAndCenterDisplay(TextWidget ctx) +{ + int left_margin = ctx->text.left_margin; + Bool visible = IsPositionVisible(ctx, ctx->text.insertPos); + + _XawTextShowPosition(ctx); + + if (XtIsRealized((Widget)ctx) && visible && + left_margin == ctx->text.left_margin) { + int insert_line = LineForPosition(ctx, ctx->text.insertPos); + int scroll_by = insert_line - (ctx->text.lt.lines >> 1); + Boolean clear_to_eol = ctx->text.clear_to_eol; + + XawTextScroll(ctx, scroll_by, 0); + SinkClearToBG(ctx->text.sink, 0, 0, XtWidth(ctx), XtHeight(ctx)); + ClearWindow(ctx); + clear_to_eol = ctx->text.clear_to_eol; + ctx->text.clear_to_eol = False; + FlushUpdate(ctx); + ctx->text.clear_to_eol = clear_to_eol; + } +} + +/* + * Internal redisplay entire window + * Legal to call only if widget is realized + */ +static void +DisplayTextWindow(Widget w) +{ + TextWidget ctx = (TextWidget)w; + + _XawTextBuildLineTable(ctx, ctx->text.lt.top, False); + ClearWindow(ctx); +} + +static void +TextSinkResize(Widget w) +{ + if (w && XtClass(w)->core_class.resize) + XtClass(w)->core_class.resize(w); +} + +/* ARGSUSED */ +void +_XawTextCheckResize(TextWidget ctx) +{ + return; +} + +/* + * Converts (params, num_params) to a list of atoms & caches the + * list in the TextWidget instance. + */ +Atom * +_XawTextSelectionList(TextWidget ctx, String *list, Cardinal nelems) +{ + Atom *sel = ctx->text.s.selections; + Display *dpy = XtDisplay((Widget)ctx); + int n; + + if (nelems > (Cardinal)ctx->text.s.array_size) { + sel = (Atom *)XtRealloc((char *)sel, sizeof(Atom) * nelems); + ctx->text.s.array_size = nelems; + ctx->text.s.selections = sel; + } + for (n = nelems; --n >= 0; sel++, list++) + *sel = XInternAtom(dpy, *list, False); + ctx->text.s.atom_count = nelems; + + return (ctx->text.s.selections); +} + +/* + * Function: + * SetSelection + * + * Parameters: + * ctx - text widget + * defaultSel - default selection + * l - left and right ends of the selection + * r - "" + * list - the selection list (as strings). + * nelems - "" + * + * Description: + * Sets the current selection. + * + * Note: + * if (ctx->text.s.left >= ctx->text.s.right) then the selection is unset + */ +void +_XawTextSetSelection(TextWidget ctx, XawTextPosition l, XawTextPosition r, + String *list, Cardinal nelems) +{ + if (nelems == 1 && !strcmp (list[0], "none")) + return; + if (nelems == 0) { + static String defaultSel = "PRIMARY"; + list = &defaultSel; + nelems = 1; + } + _SetSelection(ctx, l, r, _XawTextSelectionList(ctx, list, nelems), nelems); +} + +/* + * Function: + * ModifySelection + * + * Parameters: + * ctx - text widget + * left - left and right ends of the selection + * right - "" + * + * Description: + * Modifies the current selection. + * + * Note: + * if (ctx->text.s.left >= ctx->text.s.right) then the selection is unset + */ +static void +ModifySelection(TextWidget ctx, XawTextPosition left, XawTextPosition right) +{ + if (left == right) + ctx->text.insertPos = left; + _SetSelection(ctx, left, right, NULL, 0); +} + +/* + * This routine is used to perform various selection functions. The goal is + * to be able to specify all the more popular forms of draw-through and + * multi-click selection user interfaces from the outside. + */ +void +_XawTextAlterSelection(TextWidget ctx, XawTextSelectionMode mode, + XawTextSelectionAction action, String *params, + Cardinal *num_params) +{ + XawTextPosition position; + Boolean flag; + + /* + * This flag is used by TextPop.c:DoReplace() to determine if the selection + * is okay to use, or if it has been modified. + */ + if (ctx->text.search != NULL) + ctx->text.search->selection_changed = True; + + position = PositionForXY(ctx, (int) ctx->text.ev_x, (int) ctx->text.ev_y); + + flag = (action != XawactionStart); + if (mode == XawsmTextSelect) + DoSelection(ctx, position, ctx->text.time, flag); + else /* mode == XawsmTextExtend */ + ExtendSelection (ctx, position, flag); + + if (action == XawactionEnd) + _XawTextSetSelection(ctx, ctx->text.s.left, ctx->text.s.right, + params, *num_params); +} + +/* + * Function: + * UpdateTextInRectangle + * + * Parameters: + * ctx - the text widget + * rect - rectangle + * + * Description: + * Updates the text in the given rectangle + */ +static void +UpdateTextInRectangle(TextWidget ctx, XRectangle *rect) +{ + XawTextLineTable *lt; + int line, y1, y2, x2; + + y1 = rect->y; + y2 = y1 + rect->height; + x2 = rect->x + rect->width; + + for (line = 0, lt = &ctx->text.lt; line < lt->lines; line++) + if (lt->info[line + 1].y > y1) + break; + for (; line <= lt->lines; line++) { + if (lt->info[line].y > y2) + break; + UpdateTextInLine(ctx, line, rect->x, x2); + } +} + +/* + * This routine processes all "expose region" XEvents. In general, its job + * is to the best job at minimal re-paint of the text, displayed in the + * window, that it can. + */ +/* ARGSUSED */ +static void +XawTextExpose(Widget w, XEvent *event, Region region) +{ + TextWidget ctx = (TextWidget)w; + Boolean clear_to_eol; + XRectangle expose; + + if (event->type == Expose) { + expose.x = event->xexpose.x; + expose.y = event->xexpose.y; + expose.width = event->xexpose.width; + expose.height = event->xexpose.height; + } + else if (event->type == GraphicsExpose) { + expose.x = event->xgraphicsexpose.x; + expose.y = event->xgraphicsexpose.y; + expose.width = event->xgraphicsexpose.width; + expose.height = event->xgraphicsexpose.height; + } + else + return; + + _XawTextPrepareToUpdate(ctx); + + if (Superclass->core_class.expose) + (*Superclass->core_class.expose)(w, event, region); + + clear_to_eol = ctx->text.clear_to_eol; + ctx->text.clear_to_eol = False; + + UpdateTextInRectangle(ctx, &expose); + XawTextSinkGetCursorBounds(ctx->text.sink, &expose); + UpdateTextInRectangle(ctx, &expose); + SinkClearToBG(ctx->text.sink, expose.x, expose.y, + expose.width, expose.height); + _XawTextExecuteUpdate(ctx); + ctx->text.clear_to_eol = clear_to_eol; +} + +/* + * This routine does all setup required to syncronize batched screen updates + */ +void +_XawTextPrepareToUpdate(TextWidget ctx) +{ + if (ctx->text.old_insert < 0) { + InsertCursor((Widget)ctx, XawisOff); + ctx->text.showposition = False; + ctx->text.old_insert = ctx->text.insertPos; + ctx->text.clear_to_eol = False; +#ifndef OLDXAW + ctx->text.source_changed = SRC_CHANGE_NONE; +#endif + } +} + +/* + * This is a private utility routine used by _XawTextExecuteUpdate. It + * processes all the outstanding update requests and merges update + * ranges where possible. + */ +static void +FlushUpdate(TextWidget ctx) +{ + XmuSegment *seg; + void (*display_text)(Widget, XawTextPosition, XawTextPosition); + + if (XtIsRealized((Widget)ctx)) { + ctx->text.s.right = XawMin(ctx->text.s.right, ctx->text.lastPos); + ctx->text.s.left = XawMin(ctx->text.s.left, ctx->text.s.right); + +#ifndef OLDXAW + if (XawTextSinkBeginPaint(ctx->text.sink) == False) +#endif + display_text = OldDisplayText; +#ifndef OLDXAW + else + display_text = DisplayText; +#endif + for (seg = ctx->text.update->segment; seg; seg = seg->next) + (*display_text)((Widget)ctx, + (XawTextPosition)seg->x1, + (XawTextPosition)seg->x2); +#ifndef OLDXAW + if (display_text != OldDisplayText) { + XawTextSinkDoPaint(ctx->text.sink); + XawTextSinkEndPaint(ctx->text.sink); + } +#endif + } + (void)XmuScanlineXor(ctx->text.update, ctx->text.update); +} + +static int +CountLines(TextWidget ctx, XawTextPosition left, XawTextPosition right) +{ + if (ctx->text.wrap == XawtextWrapNever || left >= right) + return (1); + else { + XawTextPosition tmp; + int dim, lines = 0, wwidth = GetMaxTextWidth(ctx); + + while (left < right) { + tmp = left; + XawTextSinkFindPosition(ctx->text.sink, left, + ctx->text.left_margin, + wwidth, ctx->text.wrap == XawtextWrapWord, + &left, &dim, &dim); + ++lines; + if (tmp == left) + ++left; + } + + return (lines); + } + /*NOTREACHED*/ +} + +static int +GetMaxTextWidth(TextWidget ctx) +{ + XRectangle cursor; + int width; + + XawTextSinkGetCursorBounds(ctx->text.sink, &cursor); + width = (int)XtWidth(ctx) - RHMargins(ctx) - cursor.width; + + return (XawMax(0, width)); +} + +/* + * Function: + * _XawTextShowPosition + * + * Parameters: + * ctx - the text widget to show the position + * + * Description: + * Makes sure the text cursor visible, scrolling the text window + * if required. + */ +void +_XawTextShowPosition(TextWidget ctx) +{ + /* + * Variable scroll is used to avoid scanning large files to calculate + * line offsets + */ + int hpixels, vlines; + XawTextPosition first, last, top, tmp; + Bool visible, scroll; + + if (!XtIsRealized((Widget)ctx)) + return; + + /* + * Checks if a horizontal scroll is required + */ + if (ctx->text.wrap == XawtextWrapNever) { + int x, vwidth, distance, dim; + XRectangle rect; + + vwidth = (int)XtWidth(ctx) - RHMargins(ctx); + last = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstEOL, XawsdLeft, 1, False); + XawTextSinkFindDistance(ctx->text.sink, last, + ctx->text.left_margin, + ctx->text.insertPos, + &distance, &first, &dim); + XawTextSinkGetCursorBounds(ctx->text.sink, &rect); + x = ctx->text.left_margin - ctx->text.r_margin.left; + + if (x + distance + rect.width > vwidth) + hpixels = x + distance + rect.width - vwidth + (vwidth >> 2); + else if (x + distance < 0) + hpixels = x + distance - (vwidth >> 2); + else + hpixels = 0; + } + else + hpixels = 0; + + visible = IsPositionVisible(ctx, ctx->text.insertPos); + + /* + * If the cursor is already visible + */ + if (!hpixels && visible) + return; + + scroll = ctx->core.background_pixmap == XtUnspecifiedPixmap && !hpixels; + vlines = 0; + first = ctx->text.lt.top; + + /* + * Needs to scroll the text window + */ + if (visible) + top = ctx->text.lt.top; + else { + top = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstEOL, XawsdLeft, 1, False); + + /* + * Finds the nearest left position from ctx->text.insertPos + */ + if (ctx->text.wrap != XawtextWrapNever) { + int dim, vwidth = GetMaxTextWidth(ctx); + + last = top; + /*CONSTCOND*/ + while (1) { + tmp = last; + XawTextSinkFindPosition(ctx->text.sink, last, + ctx->text.left_margin, vwidth, + ctx->text.wrap == XawtextWrapWord, + &last, &dim, &dim); + if (last == tmp) + ++last; + if (last <= ctx->text.insertPos) + top = last; + else + break; + } + } + } + + if (scroll) { + if (ctx->text.insertPos < first) { /* Scroll Down */ + while (first > top) { + last = first; + first = SrcScan(ctx->text.source, first, + XawstEOL, XawsdLeft, 2, False); + vlines -= CountLines(ctx, first, last); + if (-vlines >= ctx->text.lt.lines) { + scroll = False; + break; + } + } + } + else if (!visible) { /* Scroll Up */ + while (first < top) { + last = first; + first = SrcScan(ctx->text.source, first, + XawstEOL, XawsdRight, 1, True); + vlines += CountLines(ctx, last, first); + if (vlines > ctx->text.lt.lines) { + scroll = False; + break; + } + } + } + else + scroll = False; + } + + /* + * If a portion of the text that will be scrolled is visible + */ + if (scroll) + XawTextScroll(ctx, vlines ? vlines - (ctx->text.lt.lines >> 1) : 0, 0); + /* + * Else redraw the entire text window + */ + else { + ctx->text.left_margin -= hpixels; + if (ctx->text.left_margin > ctx->text.r_margin.left) + ctx->text.left_margin = ctx->text.margin.left = + ctx->text.r_margin.left; + + if (!visible) { + vlines = ctx->text.lt.lines >> 1; + if (vlines) + top = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstEOL, XawsdLeft, vlines + 1, False); + + if (ctx->text.wrap != XawtextWrapNever) { + int dim; + int n_lines = CountLines(ctx, top, ctx->text.insertPos); + int vwidth = GetMaxTextWidth(ctx); + + while (n_lines-- > vlines) { + tmp = top; + XawTextSinkFindPosition(ctx->text.sink, top, + ctx->text.left_margin, + vwidth, + ctx->text.wrap == XawtextWrapWord, + &top, &dim, &dim); + if (tmp == top) + ++top; + } + } + _XawTextBuildLineTable(ctx, top, True); + } + else + ClearWindow(ctx); + } + ctx->text.clear_to_eol = True; +} + +#ifndef OLDXAW +static int +ResolveLineNumber(TextWidget ctx) +{ + int line_number = ctx->text.lt.base_line; + XawTextPosition position = ctx->text.lt.top; + + if (ctx->text.lt.base_line < 1) + return (ctx->text.line_number); + + if (ctx->text.wrap == XawtextWrapNever + && IsPositionVisible(ctx, ctx->text.insertPos)) + line_number += LineForPosition(ctx, ctx->text.insertPos); + else if (position < ctx->text.insertPos) { + while (position < ctx->text.insertPos) { + position = SrcScan(ctx->text.source, position, + XawstEOL, XawsdRight, 1, True); + if (position <= ctx->text.insertPos) { + ++line_number; + if (position == ctx->text.lastPos) { + line_number -= !_XawTextSourceNewLineAtEOF(ctx->text.source); + break; + } + } + } + } + else if (position > ctx->text.insertPos) { + while (position > ctx->text.insertPos) { + position = SrcScan(ctx->text.source, position, + XawstEOL, XawsdLeft, 1, False); + if (--position >= ctx->text.insertPos) + --line_number; + } + } + + return (line_number); +} +#endif + +/* + * This routine causes all batched screen updates to be performed + */ +void +_XawTextExecuteUpdate(TextWidget ctx) +{ + if (ctx->text.update_disabled || ctx->text.old_insert < 0) + return; + + if(ctx->text.old_insert != ctx->text.insertPos || ctx->text.showposition) + _XawTextShowPosition(ctx); + + FlushUpdate(ctx); + InsertCursor((Widget)ctx, XawisOn); + ctx->text.old_insert = -1; +#ifndef OLDXAW + _XawTextSetLineAndColumnNumber(ctx, False); +#endif +} + +static void +XawTextDestroy(Widget w) +{ + TextWidget ctx = (TextWidget)w; + + DestroyHScrollBar(ctx); + DestroyVScrollBar(ctx); + + XtFree((char *)ctx->text.s.selections); + XtFree((char *)ctx->text.lt.info); + XtFree((char *)ctx->text.search); + XmuDestroyScanline(ctx->text.update); + XtReleaseGC((Widget)ctx, ctx->text.gc); +} + +/* + * by the time we are managed (and get this far) we had better + * have both a source and a sink + */ +static void +XawTextResize(Widget w) +{ + TextWidget ctx = (TextWidget)w; + + PositionVScrollBar(ctx); + PositionHScrollBar(ctx); + TextSinkResize(ctx->text.sink); + + ctx->text.showposition = True; + _XawTextBuildLineTable(ctx, ctx->text.lt.top, True); +} + +/* + * This routine allow the application program to Set attributes. + */ +/*ARGSUSED*/ +static Boolean +XawTextSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + TextWidget oldtw = (TextWidget)current; + TextWidget newtw = (TextWidget)cnew; + Boolean redisplay = False; + Boolean display_caret = newtw->text.display_caret; +#ifndef OLDXAW + Boolean show_lc = False; +#endif + + newtw->text.display_caret = oldtw->text.display_caret; + _XawTextPrepareToUpdate(newtw); + newtw->text.display_caret = display_caret; + + if (oldtw->text.r_margin.left != newtw->text.r_margin.left) { + newtw->text.left_margin = newtw->text.margin.left = + newtw->text.r_margin.left; + if (newtw->text.vbar != NULL) { + newtw->text.left_margin += XtWidth(newtw->text.vbar) + + XtBorderWidth(newtw->text.vbar); + } + redisplay = True; + } + + if (oldtw->text.scroll_vert != newtw->text.scroll_vert) { + if (newtw->text.scroll_vert == XawtextScrollAlways) + CreateVScrollBar(newtw); + else + DestroyVScrollBar(newtw); + + redisplay = True; + } + + if (oldtw->text.r_margin.bottom != newtw->text.r_margin.bottom) { + newtw->text.margin.bottom = newtw->text.r_margin.bottom; + if (newtw->text.hbar != NULL) + newtw->text.margin.bottom += newtw->text.hbar->core.height + + newtw->text.hbar->core.border_width; + redisplay = True; + } + + if (oldtw->text.scroll_horiz != newtw->text.scroll_horiz) { + if (newtw->text.scroll_horiz == XawtextScrollAlways) + CreateHScrollBar(newtw); + else + DestroyHScrollBar(newtw); + + redisplay = True; + } + + if (oldtw->text.source != newtw->text.source) { +#ifndef OLDXAW + show_lc = True; + _XawSourceRemoveText(oldtw->text.source, cnew, + oldtw->text.source && + XtParent(oldtw->text.source) == cnew); + _XawSourceAddText(newtw->text.source, cnew); +#endif + _XawTextSetSource((Widget)newtw, newtw->text.source, newtw->text.lt.top, + newtw->text.insertPos); + } + + newtw->text.redisplay_needed = False; + XtSetValues((Widget)newtw->text.source, args, *num_args); + XtSetValues((Widget)newtw->text.sink, args, *num_args); + + if (oldtw->text.wrap != newtw->text.wrap + || oldtw->text.lt.top != newtw->text.lt.top + || oldtw->text.insertPos != newtw->text.insertPos + || oldtw->text.r_margin.right != newtw->text.r_margin.right + || oldtw->text.r_margin.top != newtw->text.r_margin.top + || oldtw->text.sink != newtw->text.sink + || newtw->text.redisplay_needed) { + if (oldtw->text.wrap != newtw->text.wrap) { + newtw->text.left_margin = newtw->text.margin.left = + newtw->text.r_margin.left; + if (oldtw->text.lt.top == newtw->text.lt.top) + newtw->text.lt.top = SrcScan(newtw->text.source, 0, XawstEOL, + XawsdLeft, 1, False); + } + newtw->text.showposition = True; +#ifndef OLDXAW + show_lc = True; + newtw->text.source_changed = SRC_CHANGE_OVERLAP; +#endif + _XawTextBuildLineTable(newtw, newtw->text.lt.top, True); + redisplay = True; + } + +#ifndef OLDXAW + if (newtw->text.left_column < 0) + newtw->text.left_column = 0; + if (newtw->text.right_column < 0) + newtw->text.right_column = 0; +#endif + + _XawTextExecuteUpdate(newtw); + +#ifndef OLDXAW + if (show_lc) + _XawTextSetLineAndColumnNumber(newtw, True); +#endif + + if (redisplay) + _XawTextSetScrollBars(newtw); + + return (redisplay); +} + +/* invoked by the Simple widget's SetValues */ +static Bool +XawTextChangeSensitive(Widget w) +{ + Arg args[1]; + TextWidget tw = (TextWidget)w; + + (*(&simpleClassRec)->simple_class.change_sensitive)(w); + + XtSetArg(args[0], XtNancestorSensitive, + (tw->core.ancestor_sensitive && tw->core.sensitive)); + if (tw->text.vbar) + XtSetValues(tw->text.vbar, args, ONE); + if (tw->text.hbar) + XtSetValues(tw->text.hbar, args, ONE); + return (False); +} + +/* + * Function: + * XawTextGetValuesHook + * + * Parameters: + * w - Text Widget + * args - argument list + * num_args - number of args + * + * Description: + * This is a get values hook routine that gets the + * values in the text source and sink. + */ +static void +XawTextGetValuesHook(Widget w, ArgList args, Cardinal *num_args) +{ + XtGetValues(((TextWidget)w)->text.source, args, *num_args); + XtGetValues(((TextWidget)w)->text.sink, args, *num_args); +} + +/* + * Function: + * FindGoodPosition + * + * Parameters: + * pos - any position + * + * Description: + * Returns a valid position given any postition. + * + * Returns: + * A position between (0 and lastPos) + */ +static XawTextPosition +FindGoodPosition(TextWidget ctx, XawTextPosition pos) +{ + if (pos < 0) + return (0); + return (((pos > ctx->text.lastPos) ? ctx->text.lastPos : pos)); +} + +/* Li wrote this so the IM can find a given text position's screen position */ +void +_XawTextPosToXY(Widget w, XawTextPosition pos, Position *x, Position *y) +{ + int line, ix, iy; + + LineAndXYForPosition((TextWidget)w, pos, &line, &ix, &iy); + *x = ix; + *y = iy; +} + +/******************************************************************* +The following routines provide procedural interfaces to Text window state +setting and getting. They need to be redone so than the args code can use +them. I suggest we create a complete set that takes the context as an +argument and then have the public version lookup the context and call the +internal one. The major value of this set is that they have actual application +clients and therefore the functionality provided is required for any future +version of Text. +********************************************************************/ +void +XawTextDisplay(Widget w) +{ + TextWidget ctx = (TextWidget)w; + + if (!XtIsRealized(w)) + return; + + _XawTextPrepareToUpdate(ctx); + ctx->text.clear_to_eol = True; + DisplayTextWindow(w); + _XawTextExecuteUpdate(ctx); +} + +void +XawTextSetSelectionArray(Widget w, XawTextSelectType *sarray) +{ + ((TextWidget)w)->text.sarray = sarray; +} + +void +XawTextGetSelectionPos(Widget w, XawTextPosition *left, XawTextPosition *right) +{ + *left = ((TextWidget)w)->text.s.left; + *right = ((TextWidget)w)->text.s.right; +} + +void +_XawTextSetSource(Widget w, Widget source, + XawTextPosition top, XawTextPosition startPos) +{ + TextWidget ctx = (TextWidget)w; +#ifndef OLDXAW + Bool resolve = False; +#endif + +#ifndef OLDXAW + if (source != ctx->text.source) + _XawSourceRemoveText(ctx->text.source, w, ctx->text.source && + XtParent(ctx->text.source) == w); + _XawSourceAddText(source, w); + + if (source != ctx->text.source || ctx->text.insertPos != startPos) + resolve = True; + + ctx->text.source_changed = SRC_CHANGE_OVERLAP; +#endif + ctx->text.source = source; + ctx->text.s.left = ctx->text.s.right = 0; + ctx->text.lastPos = GETLASTPOS; + top = FindGoodPosition(ctx, top); + startPos = FindGoodPosition(ctx, startPos); + ctx->text.insertPos = ctx->text.old_insert = startPos; + _XawTextPrepareToUpdate(ctx); + + _XawTextBuildLineTable(ctx, top, True); + + _XawTextExecuteUpdate(ctx); +#ifndef OLDXAW + if (resolve) + _XawTextSetLineAndColumnNumber(ctx, True); +#endif +} + +void +XawTextSetSource(Widget w, Widget source, XawTextPosition top) +{ + _XawTextSetSource(w, source, top, top); +} + +/* + * This public routine deletes the text from startPos to endPos in a source and + * then inserts, at startPos, the text that was passed. As a side effect it + * "invalidates" that portion of the displayed text (if any), so that things + * will be repainted properly. + */ +int +XawTextReplace(Widget w, XawTextPosition startPos, XawTextPosition endPos, + XawTextBlock *text) +{ + TextWidget ctx = (TextWidget)w; + int result; +#ifndef OLDXAW + Cardinal i; + TextSrcObject src = (TextSrcObject)ctx->text.source; + + for (i = 0; i < src->textSrc.num_text; i++) + _XawTextPrepareToUpdate((TextWidget)src->textSrc.text[i]); +#else + _XawTextPrepareToUpdate(ctx); +#endif + + endPos = FindGoodPosition(ctx, endPos); + startPos = FindGoodPosition(ctx, startPos); + result = _XawTextReplace(ctx, startPos, endPos, text); + +#ifndef OLDXAW + for (i = 0; i < src->textSrc.num_text; i++) + _XawTextExecuteUpdate((TextWidget)src->textSrc.text[i]); +#else + _XawTextExecuteUpdate(ctx); +#endif + + return (result); +} + +XawTextPosition +XawTextTopPosition(Widget w) +{ + return (((TextWidget)w)->text.lt.top); +} + +XawTextPosition +XawTextLastPosition(Widget w) +{ + return (((TextWidget)w)->text.lastPos); +} + +void +XawTextSetInsertionPoint(Widget w, XawTextPosition position) +{ + TextWidget ctx = (TextWidget)w; + + _XawTextPrepareToUpdate(ctx); + ctx->text.insertPos = FindGoodPosition(ctx, position); + ctx->text.showposition = True; + ctx->text.from_left = -1; + + _XawTextExecuteUpdate(ctx); +#ifndef OLDXAW + _XawTextSetLineAndColumnNumber(ctx, False); +#endif +} + +XawTextPosition +XawTextGetInsertionPoint(Widget w) +{ + return (((TextWidget)w)->text.insertPos); +} + +/* + * Note: Must walk the selection list in opposite order from TextLoseSelection + */ +void +XawTextUnsetSelection(Widget w) +{ + TextWidget ctx = (TextWidget)w; + + while (ctx->text.s.atom_count != 0) { + Atom sel = ctx->text.s.selections[ctx->text.s.atom_count - 1]; + + if (sel != (Atom) 0) { + /* + * As selections are lost the atom_count will decrement + */ + if (GetCutBufferNumber(sel) == NOT_A_CUT_BUFFER) + XtDisownSelection(w, sel, ctx->text.time); + TextLoseSelection(w, &sel); /* In case this is a cut buffer, or + XtDisownSelection failed to call us */ + } + } +} + +void +XawTextSetSelection(Widget w, XawTextPosition left, XawTextPosition right) +{ + TextWidget ctx = (TextWidget)w; + + _XawTextPrepareToUpdate(ctx); + _XawTextSetSelection(ctx, FindGoodPosition(ctx, left), + FindGoodPosition(ctx, right), NULL, 0); + _XawTextExecuteUpdate(ctx); +} + +void +XawTextInvalidate(Widget w, XawTextPosition from, XawTextPosition to) +{ + TextWidget ctx = (TextWidget)w; + + from = FindGoodPosition(ctx, from); + to = FindGoodPosition(ctx, to); + ctx->text.lastPos = GETLASTPOS; + _XawTextPrepareToUpdate(ctx); + _XawTextNeedsUpdating(ctx, from, to); + _XawTextExecuteUpdate(ctx); +} + +/*ARGSUSED*/ +void +XawTextDisableRedisplay(Widget w) +{ + ((TextWidget)w)->text.update_disabled = True; + _XawTextPrepareToUpdate((TextWidget)w); +} + +void +XawTextEnableRedisplay(Widget w) +{ + TextWidget ctx = (TextWidget)w; + XawTextPosition lastPos; + + if (!ctx->text.update_disabled) + return; + + ctx->text.update_disabled = False; + lastPos = ctx->text.lastPos = GETLASTPOS; + ctx->text.lt.top = FindGoodPosition(ctx, ctx->text.lt.top); + ctx->text.insertPos = FindGoodPosition(ctx, ctx->text.insertPos); + + if (ctx->text.s.left > lastPos || ctx->text.s.right > lastPos) + ctx->text.s.left = ctx->text.s.right = 0; + + _XawTextExecuteUpdate(ctx); +} + +Widget +XawTextGetSource(Widget w) +{ + return (((TextWidget)w)->text.source); +} + +Widget +XawTextGetSink(Widget w) +{ + return (((TextWidget)w)->text.sink); +} + +void +XawTextDisplayCaret(Widget w, +#if NeedWidePrototypes + int display_caret +#else + Boolean display_caret +#endif +) +{ + TextWidget ctx = (TextWidget)w; + + if (XtIsRealized(w)) { + _XawTextPrepareToUpdate(ctx); + ctx->text.display_caret = display_caret; + _XawTextExecuteUpdate(ctx); + } + else + ctx->text.display_caret = display_caret; +} + +/* + * Function: + * XawTextSearch + * + * Parameters: + * w - text widget + * dir - direction to search + * text - text block containing info about the string to search for + * + * Description: + * Searches for the given text block. + * + * Returns: + * The position of the text found, or XawTextSearchError on an error + */ +XawTextPosition +XawTextSearch(Widget w, +#if NeedWidePrototypes + int dir, +#else + XawTextScanDirection dir, +#endif + XawTextBlock *text) +{ + TextWidget ctx = (TextWidget)w; + + return (SrcSearch(ctx->text.source, ctx->text.insertPos, dir, text)); +} + +TextClassRec textClassRec = { + /* core */ + { + (WidgetClass)&simpleClassRec, /* superclass */ + "Text", /* class_name */ + sizeof(TextRec), /* widget_size */ + XawTextClassInitialize, /* class_initialize */ + NULL, /* class_part_init */ + False, /* class_inited */ + XawTextInitialize, /* initialize */ + NULL, /* initialize_hook */ + XawTextRealize, /* realize */ + _XawTextActionsTable, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resource */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + XtExposeGraphicsExpose | /* compress_exposure */ + XtExposeNoExpose, + True, /* compress_enterleave */ + False, /* visible_interest */ + XawTextDestroy, /* destroy */ + XawTextResize, /* resize */ + XawTextExpose, /* expose */ + XawTextSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + XawTextGetValuesHook, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + _XawDefaultTextTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + XawTextChangeSensitive, /* change_sensitive */ + }, + /* text */ + { + NULL, /* extension */ + } +}; + +WidgetClass textWidgetClass = (WidgetClass)&textClassRec; diff --git a/src/TextAction.c b/src/TextAction.c new file mode 100644 index 0000000..7b87ce4 --- /dev/null +++ b/src/TextAction.c @@ -0,0 +1,4399 @@ +/* + +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include /* for select() and struct timeval */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" +#include "XawI18n.h" + +#define SrcScan XawTextSourceScan +#define FindDist XawTextSinkFindDistance +#define FindPos XawTextSinkFindPosition +#define MULT(w) (w->text.mult == 0 ? 4 : \ + w->text.mult == 32767 ? -4 : w->text.mult) + +#define KILL_RING_APPEND 2 +#define KILL_RING_BEGIN 3 +#define KILL_RING_YANK 100 +#define KILL_RING_YANK_DONE 98 + +#define XawTextActionMaxHexChars 100 + +/* + * Prototypes + */ +static void _DeleteOrKill(TextWidget, XawTextPosition, XawTextPosition, Bool); +static void _SelectionReceived(Widget, XtPointer, Atom*, Atom*, XtPointer, + unsigned long*, int*); +static void _LoseSelection(Widget, Atom*, char**, int*); +static void AutoFill(TextWidget); +static Boolean ConvertSelection(Widget, Atom*, Atom*, Atom*, XtPointer*, + unsigned long*, int*); +static void DeleteOrKill(TextWidget, XEvent*, XawTextScanDirection, + XawTextScanType, Bool, Bool); +static void EndAction(TextWidget); +#ifndef OLDXAW +static Bool BlankLine(Widget, XawTextPosition, int*); +static int DoFormatText(TextWidget, XawTextPosition, Bool, int, + XawTextBlock*, XawTextPosition*, int, Bool); +static int FormatText(TextWidget, XawTextPosition, Bool, + XawTextPosition*, int); +static Bool GetBlockBoundaries(TextWidget, XawTextPosition*, XawTextPosition*); +#endif +static int FormRegion(TextWidget, XawTextPosition, XawTextPosition, + XawTextPosition*, int); +static void GetSelection(Widget, Time, String*, Cardinal); +static char *IfHexConvertHexElseReturnParam(char*, int*); +static void InsertNewCRs(TextWidget, XawTextPosition, XawTextPosition, + XawTextPosition*, int); +static int InsertNewLineAndBackupInternal(TextWidget); +static int LocalInsertNewLine(TextWidget, XEvent*); +static void LoseSelection(Widget, Atom*); +static void ParameterError(Widget, String); +static Bool MatchSelection(Atom, XawTextSelection*); +static void ModifySelection(TextWidget, XEvent*, XawTextSelectionMode, + XawTextSelectionAction, String*, Cardinal*); +static void Move(TextWidget, XEvent*, XawTextScanDirection, XawTextScanType, + Bool); +static void NotePosition(TextWidget, XEvent*); +static void StartAction(TextWidget, XEvent*); +static XawTextPosition StripOutOldCRs(TextWidget, XawTextPosition, + XawTextPosition, XawTextPosition*, int); +#ifndef OLDXAW +static Bool StripSpaces(TextWidget, XawTextPosition, XawTextPosition, + XawTextPosition*, int, XawTextBlock*); +static Bool Tabify(TextWidget, XawTextPosition, XawTextPosition, + XawTextPosition*, int, XawTextBlock*); +static Bool Untabify(TextWidget, XawTextPosition, XawTextPosition, + XawTextPosition*, int, XawTextBlock*); +#endif + +/* + * Actions + */ +static void CapitalizeWord(Widget, XEvent*, String*, Cardinal*); +static void DisplayCaret(Widget, XEvent*, String*, Cardinal*); +static void Delete(Widget, XEvent*, String*, Cardinal*); +static void DeleteBackwardChar(Widget, XEvent*, String*, Cardinal*); +static void DeleteBackwardWord(Widget, XEvent*, String*, Cardinal*); +static void DeleteCurrentSelection(Widget, XEvent*, String*, Cardinal*); +static void DeleteForwardChar(Widget, XEvent*, String*, Cardinal*); +static void DeleteForwardWord(Widget, XEvent*, String*, Cardinal*); +static void DowncaseWord(Widget, XEvent*, String*, Cardinal*); +static void ExtendAdjust(Widget, XEvent*, String*, Cardinal*); +static void ExtendEnd(Widget, XEvent*, String*, Cardinal*); +static void ExtendStart(Widget, XEvent*, String*, Cardinal*); +static void FormParagraph(Widget, XEvent*, String*, Cardinal*); +#ifndef OLDXAW +static void Indent(Widget, XEvent*, String*, Cardinal*); +#endif +static void InsertChar(Widget, XEvent*, String*, Cardinal*); +static void InsertNewLine(Widget, XEvent*, String*, Cardinal*); +static void InsertNewLineAndBackup(Widget, XEvent*, String*, Cardinal*); +static void InsertNewLineAndIndent(Widget, XEvent*, String*, Cardinal*); +static void InsertSelection(Widget, XEvent*, String*, Cardinal*); +static void InsertString(Widget, XEvent*, String*, Cardinal*); +#ifndef OLDXAW +static void KeyboardReset(Widget, XEvent*, String*, Cardinal*); +#endif +static void KillBackwardWord(Widget, XEvent*, String*, Cardinal*); +static void KillCurrentSelection(Widget, XEvent*, String*, Cardinal*); +static void KillForwardWord(Widget, XEvent*, String*, Cardinal*); +#ifndef OLDXAW +static void KillRingYank(Widget, XEvent*, String*, Cardinal*); +#endif +static void KillToEndOfLine(Widget, XEvent*, String*, Cardinal*); +static void KillToEndOfParagraph(Widget, XEvent*, String*, Cardinal*); +static void MoveBackwardChar(Widget, XEvent*, String*, Cardinal*); +static void MoveBackwardWord(Widget, XEvent*, String*, Cardinal*); +static void MoveBackwardParagraph(Widget, XEvent*, String*, Cardinal*); +static void MoveBeginningOfFile(Widget, XEvent*, String*, Cardinal*); +static void MoveEndOfFile(Widget, XEvent*, String*, Cardinal*); +static void MoveForwardChar(Widget, XEvent*, String*, Cardinal*); +static void MoveForwardWord(Widget, XEvent*, String*, Cardinal*); +static void MoveForwardParagraph(Widget, XEvent*, String*, Cardinal*); +static void MoveNextLine(Widget, XEvent*, String*, Cardinal*); +static void MoveNextPage(Widget, XEvent*, String*, Cardinal*); +static void MovePage(TextWidget, XEvent*, XawTextScanDirection); +static void MovePreviousLine(Widget, XEvent*, String*, Cardinal*); +static void MovePreviousPage(Widget, XEvent*, String*, Cardinal*); +static void MoveLine(TextWidget, XEvent*, XawTextScanDirection); +static void MoveToLineEnd(Widget, XEvent*, String*, Cardinal*); +static void MoveToLineStart(Widget, XEvent*, String*, Cardinal*); +static void Multiply(Widget, XEvent*, String*, Cardinal*); +static void NoOp(Widget, XEvent*, String*, Cardinal*); +#ifndef OLDXAW +static void Numeric(Widget, XEvent*, String*, Cardinal*); +#endif +static void Reconnect(Widget, XEvent*, String*, Cardinal*); +static void RedrawDisplay(Widget, XEvent*, String*, Cardinal*); +static void Scroll(TextWidget, XEvent*, XawTextScanDirection); +static void ScrollOneLineDown(Widget, XEvent*, String*, Cardinal*); +static void ScrollOneLineUp(Widget, XEvent*, String*, Cardinal*); +static void SelectAdjust(Widget, XEvent*, String*, Cardinal*); +static void SelectAll(Widget, XEvent*, String*, Cardinal*); +static void SelectEnd(Widget, XEvent*, String*, Cardinal*); +static void SelectSave(Widget, XEvent*, String*, Cardinal*); +static void SelectStart(Widget, XEvent*, String*, Cardinal*); +static void SelectWord(Widget, XEvent*, String*, Cardinal*); +static void SetKeyboardFocus(Widget, XEvent*, String*, Cardinal*); +static void TextEnterWindow(Widget, XEvent*, String*, Cardinal*); +static void TextFocusIn(Widget, XEvent*, String*, Cardinal*); +static void TextFocusOut(Widget, XEvent*, String*, Cardinal*); +static void TextLeaveWindow(Widget, XEvent*, String*, Cardinal*); +static void TransposeCharacters(Widget, XEvent*, String*, Cardinal*); +#ifndef OLDXAW +static void ToggleOverwrite(Widget, XEvent*, String*, Cardinal*); +static void Undo(Widget, XEvent*, String*, Cardinal*); +#endif +static void UpcaseWord(Widget, XEvent*, String*, Cardinal*); +static void DestroyFocusCallback(Widget, XtPointer, XtPointer); + +/* + * External + */ +void _XawTextZapSelection(TextWidget, XEvent*, Bool); + +/* + * Defined in TextPop.c + */ +void _XawTextInsertFileAction(Widget, XEvent*, String*, Cardinal*); +void _XawTextInsertFile(Widget, XEvent*, String*, Cardinal*); +void _XawTextSearch(Widget, XEvent*, String*, Cardinal*); +void _XawTextDoSearchAction(Widget, XEvent*, String*, Cardinal*); +void _XawTextDoReplaceAction(Widget, XEvent*, String*, Cardinal*); +void _XawTextSetField(Widget, XEvent*, String*, Cardinal*); +void _XawTextPopdownSearchAction(Widget, XEvent*, String*, Cardinal*); + +/* + * These are defined in Text.c + */ +void _XawTextAlterSelection(TextWidget, XawTextSelectionMode, + XawTextSelectionAction, String*, Cardinal*); +void _XawTextClearAndCenterDisplay(TextWidget); +void _XawTextExecuteUpdate(TextWidget); +char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition); +void _XawTextPrepareToUpdate(TextWidget); +int _XawTextReplace(TextWidget, XawTextPosition, XawTextPosition, + XawTextBlock*); +Atom *_XawTextSelectionList(TextWidget, String*, Cardinal); +void _XawTextSetSelection(TextWidget, XawTextPosition, XawTextPosition, + String*, Cardinal); +void _XawTextVScroll(TextWidget, int); +void XawTextScroll(TextWidget, int, int); +void _XawTextSetLineAndColumnNumber(TextWidget, Bool); + +#ifndef OLDXAW +/* + * Defined in TextSrc.c + */ +Bool _XawTextSrcUndo(TextSrcObject, XawTextPosition*); +Bool _XawTextSrcToggleUndo(TextSrcObject); +void _XawSourceSetUndoErase(TextSrcObject, int); +void _XawSourceSetUndoMerge(TextSrcObject, Bool); +#endif /* OLDXAW */ + +/* + * Initialization + */ +#ifndef OLDXAW +#define MAX_KILL_RINGS 1024 +XawTextKillRing *xaw_text_kill_ring; +static XawTextKillRing kill_ring_prev, kill_ring_null = { &kill_ring_prev, }; +static unsigned num_kill_rings; +#endif + +/* + * Implementation + */ +static void +ParameterError(Widget w, String param) +{ + String params[2]; + Cardinal num_params = 2; + params[0] = XtName(w); + params[1] = param; + + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "parameterError", "textAction", "XawError", + "Widget: %s Parameter: %s", + params, &num_params); + XBell(XtDisplay(w), 50); +} + +static void +StartAction(TextWidget ctx, XEvent *event) +{ +#ifndef OLDXAW + Cardinal i; + TextSrcObject src = (TextSrcObject)ctx->text.source; + + for (i = 0; i < src->textSrc.num_text; i++) + _XawTextPrepareToUpdate((TextWidget)src->textSrc.text[i]); + _XawSourceSetUndoMerge(src, False); +#else + _XawTextPrepareToUpdate(ctx); +#endif + + if (event != NULL) { + switch (event->type) { + case ButtonPress: + case ButtonRelease: + ctx->text.time = event->xbutton.time; + break; + case KeyPress: + case KeyRelease: + ctx->text.time = event->xkey.time; + break; + case MotionNotify: + ctx->text.time = event->xmotion.time; + break; + case EnterNotify: + case LeaveNotify: + ctx->text.time = event->xcrossing.time; + } + } +} + +static void +NotePosition(TextWidget ctx, XEvent *event) +{ + switch (event->type) { + case ButtonPress: + case ButtonRelease: + ctx->text.ev_x = event->xbutton.x; + ctx->text.ev_y = event->xbutton.y; + break; + case KeyPress: + case KeyRelease: { + XRectangle cursor; + XawTextSinkGetCursorBounds(ctx->text.sink, &cursor); + ctx->text.ev_x = cursor.x + cursor.width / 2; + ctx->text.ev_y = cursor.y + cursor.height / 2; + } break; + case MotionNotify: + ctx->text.ev_x = event->xmotion.x; + ctx->text.ev_y = event->xmotion.y; + break; + case EnterNotify: + case LeaveNotify: + ctx->text.ev_x = event->xcrossing.x; + ctx->text.ev_y = event->xcrossing.y; + } +} + +static void +EndAction(TextWidget ctx) +{ +#ifndef OLDXAW + Cardinal i; + TextSrcObject src = (TextSrcObject)ctx->text.source; + + for (i = 0; i < src->textSrc.num_text; i++) + _XawTextExecuteUpdate((TextWidget)src->textSrc.text[i]); + + ctx->text.mult = 1; + ctx->text.numeric = False; + if (ctx->text.kill_ring) { + if (--ctx->text.kill_ring == KILL_RING_YANK_DONE) { + if (ctx->text.kill_ring_ptr) { + --ctx->text.kill_ring_ptr->refcount; + ctx->text.kill_ring_ptr = NULL; + } + } + } +#else + ctx->text.mult = 1; + _XawTextExecuteUpdate(ctx); +#endif /* OLDXAW */ +} + +struct _SelectionList { + String* params; + Cardinal count; + Time time; + int asked; /* which selection currently has been asked for: + 0 = UTF8_STRING, 1 = COMPOUND_TEXT, 2 = STRING */ + Atom selection; /* selection atom (normally XA_PRIMARY) */ +}; + +/*ARGSUSED*/ +static void +_SelectionReceived(Widget w, XtPointer client_data, Atom *selection, + Atom *type, XtPointer value, unsigned long *length, + int *format) +{ + Display *d = XtDisplay(w); + TextWidget ctx = (TextWidget)w; + XawTextBlock text; + + if (*type == 0 /*XT_CONVERT_FAIL*/ || *length == 0) { + struct _SelectionList* list = (struct _SelectionList*)client_data; + + if (list != NULL) { + if (list->asked == 0) { + /* If we just asked for XA_UTF8_STRING and got no response, + we'll ask again, this time for XA_COMPOUND_TEXT. */ + list->asked++; + XtGetSelectionValue(w, list->selection, XA_COMPOUND_TEXT(d), + _SelectionReceived, + (XtPointer)list, list->time); + } else if (list->asked == 1) { + /* If we just asked for XA_COMPOUND_TEXT and got no response, + we'll ask again, this time for XA_STRING. */ + list->asked++; + XtGetSelectionValue(w, list->selection, XA_STRING, + _SelectionReceived, + (XtPointer)list, list->time); + } else { + /* We tried all possible text targets in this param. + Recurse on the tail of the params list. */ + GetSelection(w, list->time, list->params, list->count); + XtFree(client_data); + } + } + return; + } + + StartAction(ctx, NULL); + if (XawTextFormat(ctx, XawFmtWide)) { + XTextProperty textprop; + wchar_t **wlist; + int count; + + textprop.encoding = *type; + textprop.value = (unsigned char *)value; + textprop.nitems = strlen(value); + textprop.format = 8; + + if (XwcTextPropertyToTextList(d, &textprop, &wlist, &count) + != Success + || count < 1) { + XwcFreeStringList(wlist); + + /* Notify the user on strerr and in the insertion :) */ + fprintf(stderr, "Xaw Text Widget: An attempt was made to insert " + "an illegal selection.\n"); + + textprop.value = (unsigned char *)" >> ILLEGAL SELECTION << "; + textprop.nitems = strlen((char *) textprop.value); + if (XwcTextPropertyToTextList(d, &textprop, &wlist, &count) + != Success + || count < 1) + return; + } + + XFree(value); + value = (XPointer)wlist[0]; + + *length = wcslen(wlist[0]); + XtFree((XtPointer)wlist); + text.format = XawFmtWide; + } + text.ptr = (char*)value; + text.firstPos = 0; + text.length = *length; + if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) { + XBell(XtDisplay(ctx), 0); + EndAction(ctx); + return; + } + + ctx->text.from_left = -1; + ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.old_insert, + XawstPositions, XawsdRight, text.length, True); + + EndAction(ctx); + XtFree(client_data); + XFree(value); /* the selection value should be freed with XFree */ +} + +static void +GetSelection(Widget w, Time timev, String *params, Cardinal num_params) +{ + Display *d = XtDisplay(w); + TextWidget ctx = (TextWidget)w; + Atom selection; + int buffer; + + selection = XInternAtom(XtDisplay(w), *params, False); + switch (selection) { + case XA_CUT_BUFFER0: buffer = 0; break; + case XA_CUT_BUFFER1: buffer = 1; break; + case XA_CUT_BUFFER2: buffer = 2; break; + case XA_CUT_BUFFER3: buffer = 3; break; + case XA_CUT_BUFFER4: buffer = 4; break; + case XA_CUT_BUFFER5: buffer = 5; break; + case XA_CUT_BUFFER6: buffer = 6; break; + case XA_CUT_BUFFER7: buffer = 7; break; + default: buffer = -1; + } + if (buffer >= 0) { + int nbytes; + unsigned long length; + int fmt8 = 8; + Atom type = XA_STRING; + char *line = XFetchBuffer(XtDisplay(w), &nbytes, buffer); + + if ((length = nbytes) != 0L) + _SelectionReceived(w, NULL, &selection, &type, line, &length, &fmt8); + else if (num_params > 1) + GetSelection(w, timev, params+1, num_params-1); + } + else { + struct _SelectionList* list; + + if (--num_params) { + list = XtNew(struct _SelectionList); + list->params = params + 1; + list->count = num_params; + list->time = timev; + list->asked = 0; + list->selection = selection; + } + else + list = NULL; + XtGetSelectionValue(w, selection, XawTextFormat(ctx, XawFmtWide) ? + XA_UTF8_STRING(d) : XA_TEXT(d), + _SelectionReceived, (XtPointer)list, timev); + } +} + +static void +InsertSelection(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + StartAction((TextWidget)w, event); /* Get Time. */ + GetSelection(w, ((TextWidget)w)->text.time, params, *num_params); + EndAction((TextWidget)w); +} + +/* + * Routines for Moving Around + */ +static void +Move(TextWidget ctx, XEvent *event, XawTextScanDirection dir, + XawTextScanType type, Bool include) +{ + XawTextPosition insertPos; + short mult = MULT(ctx); + + if (mult < 0) { + mult = -mult; + dir = dir == XawsdLeft ? XawsdRight : XawsdLeft; + } + + insertPos = SrcScan(ctx->text.source, ctx->text.insertPos, + type, dir, mult, include); + + StartAction(ctx, event); + + if (ctx->text.s.left != ctx->text.s.right) + XawTextUnsetSelection((Widget)ctx); + +#ifndef OLDXAW + ctx->text.numeric = False; +#endif + ctx->text.mult = 1; + ctx->text.showposition = True; + ctx->text.from_left = -1; + ctx->text.insertPos = insertPos; + EndAction(ctx); +} + +/*ARGSUSED*/ +static void +MoveForwardChar(Widget w, XEvent *event, String *p, Cardinal *n) +{ + Move((TextWidget)w, event, XawsdRight, XawstPositions, True); +} + +/*ARGSUSED*/ +static void +MoveBackwardChar(Widget w, XEvent *event, String *p, Cardinal *n) +{ + Move((TextWidget)w, event, XawsdLeft, XawstPositions, True); +} + +static void +MoveForwardWord(Widget w, XEvent *event, String *p, Cardinal *n) +{ + if (*n && (p[0][0] == 'A' || p[0][0] == 'a')) + Move((TextWidget)w, event, XawsdRight, XawstAlphaNumeric, False); + else + Move((TextWidget)w, event, XawsdRight, XawstWhiteSpace, False); +} + +static void +MoveBackwardWord(Widget w, XEvent *event, String *p, Cardinal *n) +{ + if (*n && (p[0][0] == 'A' || p[0][0] == 'a')) + Move((TextWidget)w, event, XawsdLeft, XawstAlphaNumeric, False); + else + Move((TextWidget)w, event, XawsdLeft, XawstWhiteSpace, False); +} + +static void +MoveForwardParagraph(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + XawTextPosition position = ctx->text.insertPos; + short mult = MULT(ctx); + + if (mult < 0) { + ctx->text.mult = -mult; + MoveBackwardParagraph(w, event, p, n); + return; + } + + while (mult--) { + position = SrcScan(ctx->text.source, position, + XawstEOL, XawsdRight, 1, False) - 1; + + while (position == SrcScan(ctx->text.source, position, + XawstEOL, XawsdRight, 1, False)) + if (++position > ctx->text.lastPos) { + mult = 0; + break; + } + + position = SrcScan(ctx->text.source, position, + XawstParagraph, XawsdRight, 1, True); + if (position != ctx->text.lastPos) + position = SrcScan(ctx->text.source, position - 1, + XawstEOL, XawsdLeft, 1, False); + else + break; + } + + if (position != ctx->text.insertPos) { + XawTextUnsetSelection(w); + StartAction(ctx, event); + ctx->text.showposition = True; + ctx->text.from_left = -1; + ctx->text.insertPos = position; + EndAction(ctx); + } + else + ctx->text.mult = 1; +} + +/*ARGSUSED*/ +static void +MoveBackwardParagraph(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + XawTextPosition position = ctx->text.insertPos; + short mult = MULT(ctx); + + if (mult < 0) { + ctx->text.mult = -mult; + MoveForwardParagraph(w, event, p, n); + return; + } + + while (mult--) { + position = SrcScan(ctx->text.source, position, + XawstEOL, XawsdLeft, 1, False) + 1; + + while (position == SrcScan(ctx->text.source, position, + XawstEOL, XawsdLeft, 1, False)) + if (--position < 0) { + mult = 0; + break; + } + + position = SrcScan(ctx->text.source, position, + XawstParagraph, XawsdLeft, 1, True); + if (position > 0 && position < ctx->text.lastPos) + ++position; + else + break; + } + + if (position != ctx->text.insertPos) { + XawTextUnsetSelection(w); + StartAction(ctx, event); + ctx->text.showposition = True; + ctx->text.from_left = -1; + ctx->text.insertPos = position; + EndAction(ctx); + } + else + ctx->text.mult = 1; +} + +/*ARGSUSED*/ +static void +MoveToLineEnd(Widget w, XEvent *event, String *p, Cardinal *n) +{ + Move((TextWidget)w, event, XawsdRight, XawstEOL, False); +} + +/*ARGSUSED*/ +static void +MoveToLineStart(Widget w, XEvent *event, String *p, Cardinal *n) +{ + Move((TextWidget)w, event, XawsdLeft, XawstEOL, False); +} + +static void +MoveLine(TextWidget ctx, XEvent *event, XawTextScanDirection dir) +{ + XawTextPosition cnew, next_line, ltemp; + int itemp, from_left; + short mult = MULT(ctx); + + StartAction(ctx, event); + + XawTextUnsetSelection((Widget)ctx); + + if (dir == XawsdLeft) + mult = mult == 0 ? 5 : mult + 1; + + cnew = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstEOL, XawsdLeft, 1, False); + + if (ctx->text.from_left < 0) + FindDist(ctx->text.sink, cnew, ctx->text.left_margin, ctx->text.insertPos, + &ctx->text.from_left, <emp, &itemp); + + cnew = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, dir, + mult, (dir == XawsdRight)); + + next_line = SrcScan(ctx->text.source, cnew, XawstEOL, XawsdRight, 1, False); + + FindPos(ctx->text.sink, cnew, ctx->text.left_margin, ctx->text.from_left, + False, &ctx->text.insertPos, &from_left, &itemp); + + if (from_left < ctx->text.from_left) { + XawTextBlock block; + + XawTextSourceRead(ctx->text.source, ctx->text.insertPos, &block, 1); + if (block.length) { + if (XawTextFormat(ctx, XawFmtWide)) { + if (*(wchar_t *)block.ptr == _Xaw_atowc(XawTAB)) + ++ctx->text.insertPos; + } + else if (block.ptr[0] == XawTAB) + ++ctx->text.insertPos; + } + } + + if (ctx->text.insertPos > next_line) + ctx->text.insertPos = next_line; + + EndAction(ctx); +} + +static void +MoveNextLine(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + short mult = MULT(ctx); + + if (mult < 0) { + ctx->text.mult = -mult; + MovePreviousLine(w, event, p, n); + return; + } + + if (ctx->text.insertPos < ctx->text.lastPos) + MoveLine(ctx, event, XawsdRight); + else + ctx->text.mult = 1; +} + +static void +MovePreviousLine(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + short mult = MULT(ctx); + + if (mult < 0) { + ctx->text.mult = -mult; + MoveNextLine(w, event, p, n); + return; + } + + if (ctx->text.lt.top != 0 || (ctx->text.lt.lines > 1 && + ctx->text.insertPos >= ctx->text.lt.info[1].position)) + MoveLine(ctx, event, XawsdLeft); + else + ctx->text.mult = 1; +} + +/*ARGSUSED*/ +static void +MoveBeginningOfFile(Widget w, XEvent *event, String *p, Cardinal *n) +{ + Move((TextWidget)w, event, XawsdLeft, XawstAll, True); +} + +/*ARGSUSED*/ +static void +MoveEndOfFile(Widget w, XEvent *event, String *p, Cardinal *n) +{ + Move((TextWidget)w, event, XawsdRight, XawstAll, True); +} + +static void +Scroll(TextWidget ctx, XEvent *event, XawTextScanDirection dir) +{ + short mult = MULT(ctx); + + if (mult < 0) { + mult = -mult; + dir = dir == XawsdLeft ? XawsdRight : XawsdLeft; + } + + if (ctx->text.lt.lines > 1 + && (dir == XawsdRight + || ctx->text.lastPos >= ctx->text.lt.info[1].position)) { + StartAction(ctx, event); + + if (dir == XawsdLeft) + _XawTextVScroll(ctx, mult); + else + _XawTextVScroll(ctx, -mult); + + EndAction(ctx); + } + else { + ctx->text.mult = 1; +#ifndef OLDXAW + ctx->text.numeric = False; +#endif + } +} + +/*ARGSUSED*/ +static void +ScrollOneLineUp(Widget w, XEvent *event, String *p, Cardinal *n) +{ + Scroll((TextWidget)w, event, XawsdLeft); +} + +/*ARGSUSED*/ +static void +ScrollOneLineDown(Widget w, XEvent *event, String *p, Cardinal *n) +{ + Scroll((TextWidget)w, event, XawsdRight); +} + +static void +MovePage(TextWidget ctx, XEvent *event, XawTextScanDirection dir) +{ + int scroll_val = 0; + XawTextPosition old_pos; + + ctx->text.from_left = -1; + switch (dir) { + case XawsdLeft: + if (ctx->text.lt.top != 0) + scroll_val = -Max(1, ctx->text.lt.lines - 1); + break; + case XawsdRight: + if (!IsPositionVisible(ctx, Max(0, ctx->text.lastPos))) + scroll_val = Max(1, ctx->text.lt.lines - 1); + break; + } + + if (scroll_val) + XawTextScroll(ctx, scroll_val, + ctx->text.left_margin - ctx->text.r_margin.left); + + old_pos = ctx->text.insertPos; + switch (dir) { + case XawsdRight: + if (IsPositionVisible(ctx, Max(0, ctx->text.lastPos))) + ctx->text.insertPos = Max(0, ctx->text.lastPos); + else + ctx->text.insertPos = ctx->text.lt.top; + if (ctx->text.insertPos < old_pos) + ctx->text.insertPos = SrcScan(ctx->text.source, old_pos, + XawstEOL, XawsdLeft, 1, False); + break; + case XawsdLeft: + if (IsPositionVisible(ctx, 0)) + ctx->text.insertPos = 0; + else if (ctx->text.lt.lines) + ctx->text.insertPos = + ctx->text.lt.info[ctx->text.lt.lines - 1].position; + else + ctx->text.insertPos = ctx->text.lt.top; + if (ctx->text.insertPos > old_pos) + ctx->text.insertPos = SrcScan(ctx->text.source, old_pos, + XawstEOL, XawsdLeft, 1, False); + break; + } +} + +static void +MoveNextPage(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + short mult = MULT(ctx); + + if (mult < 0) { + ctx->text.mult = -mult; + MovePreviousPage(w, event, p, n); + return; + } + + if (ctx->text.insertPos < ctx->text.lastPos) { + XawTextUnsetSelection(w); + StartAction(ctx, event); + ctx->text.clear_to_eol = True; + while (mult-- && ctx->text.insertPos < ctx->text.lastPos) + MovePage(ctx, event, XawsdRight); + EndAction(ctx); + } + else + ctx->text.mult = 1; +} + +/*ARGSUSED*/ +static void +MovePreviousPage(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + short mult = MULT(ctx); + + if (mult < 0) { + ctx->text.mult = -mult; + MoveNextPage(w, event, p, n); + return; + } + + if (ctx->text.insertPos > 0) { + XawTextUnsetSelection(w); + StartAction(ctx, event); + ctx->text.clear_to_eol = True; + while (mult-- && ctx->text.insertPos > 0) + MovePage(ctx, event, XawsdLeft); + EndAction(ctx); + } + else + ctx->text.mult = 1; +} + +/* + * Delete Routines + */ +static Bool +MatchSelection(Atom selection, XawTextSelection *s) +{ + Atom *match; + int count; + + for (count = 0, match = s->selections; count < s->atom_count; + match++, count++) + if (*match == selection) + return (True); + + return (False); +} + +#define SrcCvtSel XawTextSourceConvertSelection + +static Boolean +ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type, + XtPointer *value, unsigned long *length, int *format) +{ + Display *d = XtDisplay(w); + TextWidget ctx = (TextWidget)w; + Widget src = ctx->text.source; + XawTextEditType edit_mode; + Arg args[1]; + XawTextSelectionSalt *salt = NULL; + XawTextSelection *s; + + if (*target == XA_TARGETS(d)) { + Atom *targetP, *std_targets; + unsigned long std_length; + + if (SrcCvtSel(src, selection, target, type, value, length, format)) + return (True); + + XtSetArg(args[0], XtNeditType,&edit_mode); + XtGetValues(src, args, 1); + + XmuConvertStandardSelection(w, ctx->text.time, selection, + target, type, (XPointer *)&std_targets, + &std_length, format); + + *length = 7 + (edit_mode == XawtextEdit) + std_length; + *value = XtMalloc((unsigned)sizeof(Atom)*(*length)); + targetP = *(Atom**)value; + *targetP++ = XA_STRING; + *targetP++ = XA_TEXT(d); + *targetP++ = XA_UTF8_STRING(d); + *targetP++ = XA_COMPOUND_TEXT(d); + *targetP++ = XA_LENGTH(d); + *targetP++ = XA_LIST_LENGTH(d); + *targetP++ = XA_CHARACTER_POSITION(d); + if (edit_mode == XawtextEdit) { + *targetP++ = XA_DELETE(d); + } + memcpy((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length); + XtFree((char*)std_targets); + *type = XA_ATOM; + *format = 32; + return (True); + } + + if (SrcCvtSel(src, selection, target, type, value, length, format)) + return (True); + + for (salt = ctx->text.salt2; salt; salt = salt->next) + if (MatchSelection (*selection, &salt->s)) + break; + if (!salt) + return (False); + s = &salt->s; + if (*target == XA_STRING + || *target == XA_TEXT(d) + || *target == XA_UTF8_STRING(d) + || *target == XA_COMPOUND_TEXT(d)) { + if (*target == XA_TEXT(d)) { + if (XawTextFormat(ctx, XawFmtWide)) + *type = XA_COMPOUND_TEXT(d); + else + *type = XA_STRING; + } + else + *type = *target; + + /* + * If salt is True, the salt->contents stores CT string, + * its length is measured in bytes. + * Refer to _XawTextSaltAwaySelection() + * + * by Li Yuhong, Mar. 20, 1991. + */ + if (!salt) { + *value = (char *)_XawTextGetSTRING(ctx, s->left, s->right); + if (XawTextFormat(ctx, XawFmtWide)) { + XTextProperty textprop; + if (XwcTextListToTextProperty(d, (wchar_t**)value, 1, + XCompoundTextStyle, &textprop) + < Success) { + XtFree(*value); + return (False); + } + XtFree(*value); + *value = (XtPointer)textprop.value; + *length = textprop.nitems; + } + else + *length = strlen(*value); + } + else { + *value = XtMalloc((salt->length + 1) * sizeof(unsigned char)); + strcpy (*value, salt->contents); + *length = salt->length; + } + /* Got *value,*length, now in COMPOUND_TEXT format. */ + if (XawTextFormat(ctx, XawFmtWide)) { + if (*type == XA_STRING) { + XTextProperty textprop; + wchar_t **wlist; + int count; + + textprop.encoding = XA_COMPOUND_TEXT(d); + textprop.value = (unsigned char *)*value; + textprop.nitems = strlen(*value); + textprop.format = 8; + if (XwcTextPropertyToTextList(d, &textprop, &wlist, &count) + < Success + || count < 1) { + XtFree(*value); + return (False); + } + XtFree(*value); + if (XwcTextListToTextProperty(d, wlist, 1, XStringStyle, &textprop) + < Success) { + XwcFreeStringList((wchar_t**)wlist); + return (False); + } + *value = (XtPointer)textprop.value; + *length = textprop.nitems; + XwcFreeStringList((wchar_t**) wlist); + } + else if (*type == XA_UTF8_STRING(d)) { + XTextProperty textprop; + char **list; + int count; + + textprop.encoding = XA_COMPOUND_TEXT(d); + textprop.value = (unsigned char *)*value; + textprop.nitems = strlen(*value); + textprop.format = 8; + if (Xutf8TextPropertyToTextList(d, &textprop, &list, &count) + < Success + || count < 1) { + XtFree(*value); + return (False); + } + XtFree(*value); + *value = *list; + *length = strlen(*list); + XFree(list); + } + } + *format = 8; + return (True); + } + + if (*target == XA_LIST_LENGTH(d) || *target == XA_LENGTH(d)) { + long *temp; + + temp = (long *)XtMalloc(sizeof(long)); + if (*target == XA_LIST_LENGTH(d)) + *temp = 1L; + else /* *target == XA_LENGTH(d) */ + *temp = (long)(s->right - s->left); + + *value = (XPointer)temp; + *type = XA_INTEGER; + *length = 1L; + *format = 32; + return (True); + } + + if (*target == XA_CHARACTER_POSITION(d)) { + long *temp; + + temp = (long *) XtMalloc(2 * sizeof(long)); + temp[0] = (long)(s->left + 1); + temp[1] = s->right; + *value = (XPointer)temp; + *type = XA_SPAN(d); + *length = 2L; + *format = 32; + return (True); + } + + if (*target == XA_DELETE(d)) { + if (!salt) + _XawTextZapSelection(ctx, NULL, True); + *value = NULL; + *type = XA_NULL(d); + *length = 0; + *format = 32; + return (True); + } + + if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type, + (XPointer *)value, length, format)) + return (True); + + return (False); +} + +static void +LoseSelection(Widget w, Atom *selection) +{ + _LoseSelection(w, selection, NULL, NULL); +} + +static void +_LoseSelection(Widget w, Atom *selection, char **contents, int *length) +{ + TextWidget ctx = (TextWidget)w; + Atom *atomP; + int i; + XawTextSelectionSalt *salt, *prevSalt, *nextSalt; + + prevSalt = 0; + for (salt = ctx->text.salt2; salt; salt = nextSalt) { + atomP = salt->s.selections; + nextSalt = salt->next; + for (i = 0 ; i < salt->s.atom_count; i++, atomP++) + if (*selection == *atomP) + *atomP = (Atom)0; + + while (salt->s.atom_count + && salt->s.selections[salt->s.atom_count-1] == 0) + salt->s.atom_count--; + + /* + * Must walk the selection list in opposite order from UnsetSelection. + */ + atomP = salt->s.selections; + for (i = 0 ; i < salt->s.atom_count; i++, atomP++) + if (*atomP == (Atom)0) { + *atomP = salt->s.selections[--salt->s.atom_count]; + + while (salt->s.atom_count + && salt->s.selections[salt->s.atom_count-1] == 0) + salt->s.atom_count--; + } + if (salt->s.atom_count == 0) { +#ifndef OLDXAW + if (contents == NULL) { + XawTextKillRing *kill_ring = XtNew(XawTextKillRing); + + kill_ring->next = xaw_text_kill_ring; + kill_ring->contents = salt->contents; + kill_ring->length = salt->length; + kill_ring->format = XawFmt8Bit; + xaw_text_kill_ring = kill_ring; + kill_ring_prev.next = xaw_text_kill_ring; + + if (++num_kill_rings > MAX_KILL_RINGS) { + XawTextKillRing *tail = NULL; + + while (kill_ring->next) { + tail = kill_ring; + kill_ring = kill_ring->next; + } + if (kill_ring->refcount == 0) { + --num_kill_rings; + tail->next = NULL; + XtFree(kill_ring->contents); + XtFree((char*)kill_ring); + } + } + } + else { + *contents = salt->contents; + *length = salt->length; + } +#endif + if (prevSalt) + prevSalt->next = nextSalt; + else + ctx->text.salt2 = nextSalt; + + XtFree((char *)salt->s.selections); + XtFree((char *)salt); + } + else + prevSalt = salt; + } +} + +static void +_DeleteOrKill(TextWidget ctx, XawTextPosition from, XawTextPosition to, + Bool kill) +{ + XawTextBlock text; + +#ifndef OLDXAW + if (ctx->text.kill_ring_ptr) { + --ctx->text.kill_ring_ptr->refcount; + ctx->text.kill_ring_ptr = NULL; + } +#endif + if (kill && from < to) { +#ifndef OLDXAW + Bool append = False; + char *ring = NULL; + XawTextPosition old_from = from; +#endif + char *string; + int size = 0, length; + XawTextSelectionSalt *salt; + Atom selection = XInternAtom(XtDisplay(ctx), "SECONDARY", False); + +#ifndef OLDXAW + if (ctx->text.kill_ring == KILL_RING_APPEND) { + old_from = ctx->text.salt2->s.left; + append = True; + } + else + ctx->text.kill_ring = KILL_RING_BEGIN; + + if (append) + _LoseSelection((Widget)ctx, &selection, &ring, &size); + else +#endif + LoseSelection((Widget)ctx, &selection); + + salt = (XawTextSelectionSalt*)XtMalloc(sizeof(XawTextSelectionSalt)); + salt->s.selections = (Atom *)XtMalloc(sizeof(Atom)); + salt->s.left = from; + salt->s.right = to; + + string = (char *)_XawTextGetSTRING(ctx, from, to); + + if (XawTextFormat(ctx, XawFmtWide)) { + XTextProperty textprop; + + if (XwcTextListToTextProperty(XtDisplay((Widget)ctx), + (wchar_t**)(&string), + 1, XCompoundTextStyle, + &textprop) < Success) { + XtFree(string); + XtFree((char*)salt->s.selections); + XtFree((char*)salt); + return; + } + XtFree(string); + string = (char *)textprop.value; + length = textprop.nitems; + } + else + length = strlen(string); + + salt->length = length + size; + +#ifndef OLDXAW + if (!append) + salt->contents = string; + else { + salt->contents = XtMalloc(length + size + 1); + if (from >= old_from) { + strncpy(salt->contents, ring, size); + salt->contents[size] = '\0'; + strncat(salt->contents, string, length); + } + else { + strncpy(salt->contents, string, length); + salt->contents[length] = '\0'; + strncat(salt->contents, ring, size); + } + salt->contents[length + size] = '\0'; + XtFree(ring); + XtFree(string); + } + + kill_ring_prev.contents = salt->contents; + kill_ring_prev.length = salt->length; + kill_ring_prev.format = XawFmt8Bit; +#else + salt->contents = string; +#endif + + salt->next = ctx->text.salt2; + ctx->text.salt2 = salt; + +#ifndef OLDXAW + if (append) + ctx->text.kill_ring = KILL_RING_BEGIN; +#endif + + salt->s.selections[0] = selection; + + XtOwnSelection((Widget)ctx, selection, ctx->text.time, + ConvertSelection, LoseSelection, NULL); + salt->s.atom_count = 1; + } + text.length = 0; + text.firstPos = 0; + + text.format = _XawTextFormat(ctx); + text.ptr = ""; + + if (_XawTextReplace(ctx, from, to, &text)) { + XBell(XtDisplay(ctx), 50); + return; + } + ctx->text.from_left = -1; + ctx->text.insertPos = from; + ctx->text.showposition = TRUE; +} + +static void +DeleteOrKill(TextWidget ctx, XEvent *event, XawTextScanDirection dir, + XawTextScanType type, Bool include, Bool kill) +{ + XawTextPosition from, to; + short mult = MULT(ctx); + + if (mult < 0) { + mult = -mult; + dir = dir == XawsdLeft ? XawsdRight : XawsdLeft; + } + + StartAction(ctx, event); +#ifndef OLDXAW + if (mult == 1) + _XawSourceSetUndoMerge((TextSrcObject)ctx->text.source, True); +#endif + to = SrcScan(ctx->text.source, ctx->text.insertPos, + type, dir, mult, include); + + /* + * If no movement actually happened, then bump the count and try again. + * This causes the character position at the very beginning and end of + * a boundary to act correctly + */ + if (to == ctx->text.insertPos) + to = SrcScan(ctx->text.source, ctx->text.insertPos, + type, dir, mult + 1, include); + + if (dir == XawsdLeft) { + from = to; + to = ctx->text.insertPos; + } + else + from = ctx->text.insertPos; + + _DeleteOrKill(ctx, from, to, kill); + EndAction(ctx); +} + +static void +Delete(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + + if (ctx->text.s.left != ctx->text.s.right) + DeleteCurrentSelection(w, event, p, n); + else + DeleteBackwardChar(w, event, p, n); +} + +static void +DeleteChar(Widget w, XEvent *event, XawTextScanDirection dir) +{ + TextWidget ctx = (TextWidget)w; + short mul = MULT(ctx); + + if (mul < 0) { + ctx->text.mult = mul = -mul; + dir = dir == XawsdLeft ? XawsdRight : XawsdLeft; + } + DeleteOrKill(ctx, event, dir, XawstPositions, True, False); +#ifndef OLDXAW + if (mul == 1) + _XawSourceSetUndoErase((TextSrcObject)ctx->text.source, + dir == XawsdLeft ? -1 : 1); +#endif +} + +/*ARGSUSED*/ +static void +DeleteForwardChar(Widget w, XEvent *event, String *p, Cardinal *n) +{ + DeleteChar(w, event, XawsdRight); +} + +/*ARGSUSED*/ +static void +DeleteBackwardChar(Widget w, XEvent *event, String *p, Cardinal *n) +{ + DeleteChar(w, event, XawsdLeft); +} + +static void +DeleteForwardWord(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + XawTextScanType type; + + if (*num_params && (*params[0] == 'A' || *params[0] == 'a')) + type = XawstAlphaNumeric; + else + type = XawstWhiteSpace; + + DeleteOrKill((TextWidget)w, event, XawsdRight, type, False, False); +} + +static void +DeleteBackwardWord(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + XawTextScanType type; + + if (*num_params && (*params[0] == 'A' || *params[0] == 'a')) + type = XawstAlphaNumeric; + else + type = XawstWhiteSpace; + + DeleteOrKill((TextWidget)w, event, XawsdLeft, type, False, False); +} + +static void +KillForwardWord(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + XawTextScanType type; + + if (*num_params && (*params[0] == 'A' || *params[0] == 'a')) + type = XawstAlphaNumeric; + else + type = XawstWhiteSpace; + + DeleteOrKill((TextWidget)w, event, XawsdRight, type, False, True); +} + +static void +KillBackwardWord(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + XawTextScanType type; + + if (*num_params && (*params[0] == 'A' || *params[0] == 'a')) + type = XawstAlphaNumeric; + else + type = XawstWhiteSpace; + + DeleteOrKill((TextWidget) w, event, XawsdLeft, type, False, True); +} + +/*ARGSUSED*/ +static void +KillToEndOfLine(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + XawTextPosition end_of_line; + XawTextScanDirection dir = XawsdRight; + short mult = MULT(ctx); + + if (mult < 0) { + dir = XawsdLeft; + mult = -mult; + } + + StartAction(ctx, event); + end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, + dir, mult, False); + if (end_of_line == ctx->text.insertPos) + end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, + dir, mult, True); + + if (dir == XawsdRight) + _DeleteOrKill(ctx, ctx->text.insertPos, end_of_line, True); + else + _DeleteOrKill(ctx, end_of_line, ctx->text.insertPos, True); + EndAction(ctx); +} + +/*ARGSUSED*/ +static void +KillToEndOfParagraph(Widget w, XEvent *event, String *p, Cardinal *n) +{ + DeleteOrKill((TextWidget)w, event, XawsdRight, XawstParagraph, False, True); +} + +void +_XawTextZapSelection(TextWidget ctx, XEvent *event, Bool kill) +{ + StartAction(ctx, event); + _DeleteOrKill(ctx, ctx->text.s.left, ctx->text.s.right, kill); + EndAction(ctx); +} + +/*ARGSUSED*/ +static void +KillCurrentSelection(Widget w, XEvent *event, String *p, Cardinal *n) +{ + _XawTextZapSelection((TextWidget) w, event, True); +} + +#ifndef OLDXAW +/*ARGSUSED*/ +static void +KillRingYank(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + XawTextPosition insertPos = ctx->text.insertPos; + Bool first_yank = False; + + if (ctx->text.s.left != ctx->text.s.right) + XawTextUnsetSelection((Widget)ctx); + + StartAction(ctx, event); + + if (ctx->text.kill_ring_ptr == NULL) { + ctx->text.kill_ring_ptr = &kill_ring_prev; + ++ctx->text.kill_ring_ptr->refcount; + ctx->text.s.left = ctx->text.s.right = insertPos; + first_yank = True; + } + if (ctx->text.kill_ring_ptr) { + int mul = MULT(ctx); + XawTextBlock text; + + if (!first_yank) { + if (mul < 0) + mul = 1; + --ctx->text.kill_ring_ptr->refcount; + while (mul--) { + if ((ctx->text.kill_ring_ptr = ctx->text.kill_ring_ptr->next) == NULL) + ctx->text.kill_ring_ptr = &kill_ring_null; + } + ++ctx->text.kill_ring_ptr->refcount; + } + text.firstPos = 0; + text.length = ctx->text.kill_ring_ptr->length; + text.ptr = ctx->text.kill_ring_ptr->contents; + text.format = ctx->text.kill_ring_ptr->format; + + if (_XawTextReplace(ctx, ctx->text.s.left, insertPos, &text) == XawEditDone) { + ctx->text.kill_ring = KILL_RING_YANK; + ctx->text.insertPos = ctx->text.s.left + text.length; + } + } + else + XBell(XtDisplay(w), 0); + + EndAction(ctx); +} +#endif /* OLDXAW */ + +/*ARGSUSED*/ +static void +DeleteCurrentSelection(Widget w, XEvent *event, String *p, Cardinal *n) +{ + _XawTextZapSelection((TextWidget)w, event, False); +} + +#ifndef OLDXAW +#define CHECK_SAVE() \ + if (save && !save->ptr) \ + save->ptr = _XawTextGetText(ctx, save->firstPos, \ + save->firstPos + save->length) +static Bool +StripSpaces(TextWidget ctx, XawTextPosition left, XawTextPosition right, + XawTextPosition *pos, int num_pos, XawTextBlock *save) +{ + Bool done, space; + int i, cpos, count = 0; + XawTextBlock block, text; + XawTextPosition ipos, position = left, tmp = left; + + text.firstPos = 0; + text.format = XawFmt8Bit; + text.ptr = " "; + text.length = 1; + + position = XawTextSourceRead(ctx->text.source, position, + &block, right - left); + done = False; + space = False; + /* convert tabs and returns to spaces */ + while (!done) { + if (XawTextFormat(ctx, XawFmt8Bit)) { + for (i = 0; i < block.length; i++) + if (block.ptr[i] == '\t' || block.ptr[i] == '\n') { + space = True; + break; + } + } + else { + wchar_t *wptr = (wchar_t*)block.ptr; + for (i = 0; i < block.length; i++) + if (wptr[i] == _Xaw_atowc('\t') || wptr[i] == _Xaw_atowc('\n')) { + space = True; + break; + } + } + if (space) { + CHECK_SAVE(); + if (_XawTextReplace(ctx, tmp + i, tmp + i + 1, &text)) + return (False); + space = False; + } + tmp += i; + position = XawTextSourceRead(ctx->text.source, tmp, + &block, right - tmp); + if (block.length == 0 || tmp == position || tmp >= right) + done = True; + } + + text.ptr = ""; + text.length = 0; + position = tmp = left; + position = XawTextSourceRead(ctx->text.source, position, + &block, right - left); + ipos = ctx->text.insertPos; + done = False; + while (!done) { + if (XawTextFormat(ctx, XawFmt8Bit)) { + for (i = 0; i < block.length; i++) + if (block.ptr[i] == ' ') + ++count; + else if (count == 1) + count = 0; + else if (count) + break; + } + else { + wchar_t *wptr = (wchar_t*)block.ptr; + for (i = 0; i < block.length; i++) + if (wptr[i] == _Xaw_atowc(' ')) + ++count; + else if (count == 1) + count = 0; + else if (count) + break; + } + if (--count > 0) { + CHECK_SAVE(); + if (_XawTextReplace(ctx, tmp + i - count, tmp + i, &text)) + return (False); + right -= count; + if (num_pos) { + for (cpos = 0; cpos < num_pos; cpos++) { + if (tmp + i - count < pos[cpos]) { + if (tmp + i < pos[cpos]) + pos[cpos] -= count; + else + pos[cpos] = tmp + i - count; + } + } + } + else { + if (tmp + i - count < ipos) { + if (tmp + i < ipos) + ipos -= count; + else + ipos = tmp + i - count; + } + } + tmp += i - count; + } + else + tmp += i + 1; + count = 0; + position = XawTextSourceRead(ctx->text.source, tmp, + &block, right - tmp); + if (block.length == 0 || tmp == position || tmp >= right) + done = True; + } + if (!num_pos) + ctx->text.insertPos = ipos; + + return (True); +} + +static Bool +Tabify(TextWidget ctx, XawTextPosition left, XawTextPosition right, + XawTextPosition *pos, int num_pos, XawTextBlock *save) +{ + Bool done, zero; + int i, cpos, count = 0, column = 0, offset = 0; + XawTextBlock text, block; + XawTextPosition ipos, position = left, tmp = left; + TextSinkObject sink = (TextSinkObject)ctx->text.sink; + short *char_tabs = sink->text_sink.char_tabs; + int tab_count = sink->text_sink.tab_count; + int tab_index = 0, tab_column = 0, TAB_SIZE = DEFAULT_TAB_SIZE; + + text.firstPos = 0; + text.ptr = "\t"; + text.format = XawFmt8Bit; + text.length = 1; + + position = XawTextSourceRead(ctx->text.source, position, + &block, right - left); + ipos = ctx->text.insertPos; + done = zero = False; + if (tab_count) + TAB_SIZE = *char_tabs; + while (!done) { + if (XawTextFormat(ctx, XawFmt8Bit)) { + for (i = 0; i < block.length; i++) { + ++offset; + ++column; + if (tab_count) { + if (column > tab_column + char_tabs[tab_index]) { + TAB_SIZE = tab_index < tab_count - 1 ? char_tabs[tab_index + 1] - char_tabs[tab_index] : *char_tabs; + if (++tab_index >= tab_count) { + tab_column += char_tabs[tab_count - 1]; + tab_index = 0; + } + } + } + if (block.ptr[i] == ' ') { + if (++count > TAB_SIZE) + count %= TAB_SIZE; + if ((tab_count && column == tab_column + char_tabs[tab_index]) || + (!tab_count && column % TAB_SIZE == 0)) { + if (count % (TAB_SIZE + 1) > 1) + break; + else + count = 0; + } + } + else { + if (block.ptr[i] == '\n') { + zero = True; + break; + } + count = 0; + } + } + } + else { + wchar_t *wptr = (wchar_t*)block.ptr; + for (i = 0; i < block.length; i++) { + ++offset; + ++column; + if (tab_count) { + if (column > tab_column + char_tabs[tab_index]) { + TAB_SIZE = tab_index < tab_count - 1 ? char_tabs[tab_index + 1] - char_tabs[tab_index] : *char_tabs; + if (++tab_index >= tab_count) { + tab_column += char_tabs[tab_count - 1]; + tab_index = 0; + } + } + } + if (wptr[i] == _Xaw_atowc(' ')) { + if (++count > TAB_SIZE) + count %= TAB_SIZE; + if ((tab_count && column == tab_column + char_tabs[tab_index]) || + (!tab_count && column % TAB_SIZE == 0)) { + if (count % (TAB_SIZE + 1) > 1) + break; + else + count = 0; + } + } + else { + if (wptr[i] == _Xaw_atowc('\n')) { + zero = True; + break; + } + count = 0; + } + } + } + count %= TAB_SIZE + 1; + if (!zero && count > 1 && i < block.length) { + CHECK_SAVE(); + if (_XawTextReplace(ctx, tmp + i - count + 1, tmp + i + 1, &text)) + return (False); + right -= count - 1; + offset -= count - 1; + if (num_pos) { + for (cpos = 0; cpos < num_pos; cpos++) { + if (tmp + i - count + 1 < pos[cpos]) { + if (tmp + i + 1 < pos[cpos]) + pos[cpos] -= count; + else + pos[cpos] = tmp + i - count + 1; + ++pos[cpos]; + } + } + } + else { + if (tmp + i - count + 1 < ipos) { + if (tmp + i + 1 < ipos) + ipos -= count; + else + ipos = tmp + i - count + 1; + ++ipos; + } + } + } + if (count) + --count; + if (zero) { + count = column = 0; + zero = False; + if (tab_count) { + tab_column = tab_index = 0; + TAB_SIZE = *char_tabs; + } + } + else if (i < block.length) + count = 0; + tmp = left + offset; + position = XawTextSourceRead(ctx->text.source, tmp, + &block, right - tmp); + if (tmp == position || tmp >= right) + done = True; + } + if (!num_pos) + ctx->text.insertPos = ipos; + + return (True); +} + +static Bool +Untabify(TextWidget ctx, XawTextPosition left, XawTextPosition right, + XawTextPosition *pos, int num_pos, XawTextBlock *save) +{ + Bool done, zero; + int i, cpos, count = 0, diff = 0; + XawTextBlock block, text; + XawTextPosition ipos, position = left, tmp = left; + TextSinkObject sink = (TextSinkObject)ctx->text.sink; + short *char_tabs = sink->text_sink.char_tabs; + int tab_count = sink->text_sink.tab_count; + int tab_index = 0, tab_column = 0, tab_base = 0; + static char *tabs = " "; + + text.firstPos = 0; + text.format = XawFmt8Bit; + text.ptr = tabs; + + position = XawTextSourceRead(ctx->text.source, position, + &block, right - left); + ipos = ctx->text.insertPos; + done = False; + zero = False; + while (!done) { + if (XawTextFormat(ctx, XawFmt8Bit)) + for (i = 0; i < block.length; i++) { + if (block.ptr[i] != '\t') { + ++count; + if (block.ptr[i] == '\n') { + zero = True; + break; + } + } + else + break; + } + else { + wchar_t *wptr = (wchar_t*)block.ptr; + for (i = 0; i < block.length; i++) + if (wptr[i] != _Xaw_atowc('\t')) { + ++count; + if (wptr[i] != _Xaw_atowc('\n')) { + zero = True; + break; + } + } + else + break; + } + if (!zero && i < block.length) { + if (tab_count) { + while (tab_base + tab_column <= count) { + for (; tab_index < tab_count; ++tab_index) + if (tab_base + char_tabs[tab_index] > count) { + tab_column = char_tabs[tab_index]; + break; + } + if (tab_index >= tab_count) { + tab_base += char_tabs[tab_count - 1]; + tab_column = tab_index = 0; + } + } + text.length = (tab_base + tab_column) - count; + if (text.length > 8) { + int j; + + text.ptr = XtMalloc(text.length); + for (j = 0; j < text.length; j++) + text.ptr[j] = ' '; + } + else + text.ptr = tabs; + } + else + text.length = DEFAULT_TAB_SIZE - (count % DEFAULT_TAB_SIZE); + CHECK_SAVE(); + if (_XawTextReplace(ctx, tmp + i, tmp + i + 1, &text)) { + if (tab_count && text.length > 8) + XtFree(text.ptr); + return (False); + } + if (tab_count && text.length > 8) + XtFree(text.ptr); + count += text.length; + right += text.length - 1; + if (num_pos) { + for (cpos = 0; cpos < num_pos; cpos++) { + if (tmp + i < pos[cpos]) { + if (tmp + i + 1 < pos[cpos]) + --pos[cpos]; + else + pos[cpos] = tmp + i; + pos[cpos] += text.length; + } + } + } + else { + if (tmp + i < ipos) { + if (tmp + i + 1 < ipos) + --ipos; + else + ipos = tmp + i; + ipos += text.length; + } + } + } + tmp = left + count + diff; + if (zero) { + diff += count; + count = 0; + zero = False; + if (tab_count) + tab_base = tab_column = tab_index = 0; + } + position = XawTextSourceRead(ctx->text.source, tmp, + &block, right - tmp); + if (tmp == position || tmp >= right) + done = True; + } + if (!num_pos) + ctx->text.insertPos = ipos; + + return (True); +} + +static int +FormatText(TextWidget ctx, XawTextPosition left, Bool force, + XawTextPosition *pos, int num_pos) +{ + char *ptr = NULL; + Bool freepos = False, undo, paragraph = pos != NULL; + int i, result; + XawTextBlock block, *text; + XawTextPosition end = ctx->text.lastPos, buf[32]; + TextSrcObject src = (TextSrcObject)ctx->text.source; + XawTextPosition right = SrcScan(ctx->text.source, left, XawstEOL, + XawsdRight, 1, False); + + undo = src->textSrc.enable_undo && src->textSrc.undo_state == False; + if (undo) { + if (!pos) { + num_pos = src->textSrc.num_text; + pos = XawStackAlloc(sizeof(XawTextPosition) * num_pos, buf); + for (i = 0; i < num_pos; i++) + pos[i] = ((TextWidget)src->textSrc.text[i])->text.insertPos; + freepos = True; + } + else + freepos = False; + src->textSrc.undo_state = True; + block.ptr = NULL; + block.firstPos = left; + block.length = right - left; + text = █ + } + else + text = NULL; + + result = DoFormatText(ctx, left, force, 1, text, pos, num_pos, paragraph); + if (undo && result == XawEditDone && block.ptr) { + char *lbuf, *rbuf; + unsigned llen, rlen, size; + + ptr = lbuf = block.ptr; + llen = block.length; + rlen = llen + (ctx->text.lastPos - end); + + block.firstPos = 0; + block.format = _XawTextFormat(ctx); + + rbuf = _XawTextGetText(ctx, left, left + rlen); + + size = XawTextFormat(ctx, XawFmtWide) ? sizeof(wchar_t) : sizeof(char); + if (llen != rlen || memcmp(lbuf, rbuf, llen * size)) { + block.ptr = lbuf; + block.length = llen; + _XawTextReplace(ctx, left, left + rlen, &block); + + src->textSrc.undo_state = False; + block.ptr = rbuf; + block.length = rlen; + _XawTextReplace(ctx, left, left + llen, &block); + } + else + src->textSrc.undo_state = False; + XtFree(rbuf); + } + if (undo) { + src->textSrc.undo_state = False; + if (freepos) { + for (i = 0; i < num_pos; i++) { + TextWidget tw = (TextWidget)src->textSrc.text[i]; + tw->text.insertPos = XawMin(XawMax(0, pos[i]), tw->text.lastPos); + } + XawStackFree(pos, buf); + } + if (ptr) + XtFree(ptr); + } + + return (result); +} + +static int +DoFormatText(TextWidget ctx, XawTextPosition left, Bool force, int level, + XawTextBlock *save, XawTextPosition *pos, int num_pos, + Bool paragraph) +{ + XawTextPosition right = SrcScan(ctx->text.source, left, XawstEOL, + XawsdRight, 1, False); + XawTextPosition position, tmp, ipos; + XawTextBlock block, text; + char buf[128]; + wchar_t *wptr; + int i, count, cpos; + Bool done, force2 = force, recurse = False; + + position = XawTextSourceRead(ctx->text.source, left, &block, right - left); + if (block.length == 0 || left >= right || + (level == 1 && ((XawTextFormat(ctx, XawFmt8Bit) && + block.ptr[0] != ' ' && + block.ptr[0] != '\t' && + !isalnum(*(unsigned char*)block.ptr)) || + (XawTextFormat(ctx, XawFmtWide) && + _Xaw_atowc(XawSP) != *(wchar_t*)block.ptr && + _Xaw_atowc(XawTAB) != *(wchar_t*)block.ptr && + !iswalnum(*(wchar_t*)block.ptr))))) + return (XawEditDone); + + if (level == 1 && !paragraph) { + tmp = ctx->text.lastPos; + if (Untabify(ctx, left, right, pos, num_pos, save) == False) + return (XawEditError); + right += ctx->text.lastPos - tmp; + position = XawTextSourceRead(ctx->text.source, left, &block, + right - left); + } + + text.firstPos = 0; + text.format = XawFmt8Bit; + + ipos = ctx->text.insertPos; + count = 0; + done = False; + while (!done) { + if (XawTextFormat(ctx, XawFmt8Bit)) { + for (i = 0; i < block.length; i++) + if (block.ptr[i] == ' ') + ++count; + else { + done = True; + break; + } + } + else { + wptr = (wchar_t*)block.ptr; + for (i = 0; i < block.length; i++) + if (wptr[i] == _Xaw_atowc(' ')) + ++count; + else { + done = True; + break; + } + } + tmp = position; + position = XawTextSourceRead(ctx->text.source, position, + &block, right - position); + if (tmp == position) + done = True; + } + position = left + count; + if (count < ctx->text.left_column) { + int bytes = ctx->text.left_column - count; + + text.ptr = XawStackAlloc(bytes, buf); + text.length = bytes; + for (i = 0; i < bytes; i++) + text.ptr[i] = ' '; + CHECK_SAVE(); + if (_XawTextReplace(ctx, left, left, &text)) { + XawStackFree(text.ptr, buf); + return (XawEditError); + } + XawStackFree(text.ptr, buf); + right += bytes; + if (num_pos) { + for (cpos = 0; cpos < num_pos; cpos++) + if (pos[cpos] >= left) + pos[cpos] += bytes; + } + if (ipos >= left) + ipos += bytes; + count += bytes; + } + + done = False; + if (!paragraph && level == 1 + && ipos <= right && ipos - left > ctx->text.right_column) { + XawTextPosition len = ctx->text.lastPos; + int skip = ctx->text.justify == XawjustifyRight + || ctx->text.justify == XawjustifyCenter ? + ctx->text.left_column : count; + + if (pos) + for (i = 0; i < num_pos; i++) + if (pos[i] == ipos) + break; + + StripSpaces(ctx, left + skip, right, pos, num_pos, save); + right += ctx->text.lastPos - len; + if (pos && i < num_pos) + ipos = pos[i]; + else + ipos = ctx->text.insertPos; + done = ipos - left > ctx->text.right_column; + count = skip + (count == skip + 1); + } + if ((paragraph || done) && right - left > ctx->text.right_column) { + position = tmp = right; + XawTextSourceRead(ctx->text.source, position - 1, &block, 1); + if (block.length && + ((XawTextFormat(ctx, XawFmt8Bit) && + block.ptr[0] == ' ') || + (XawTextFormat(ctx, XawFmtWide) && + _Xaw_atowc(XawSP) == *(wchar_t*)block.ptr))) + --position; + while (position - left > ctx->text.right_column) { + tmp = position; + position = SrcScan(ctx->text.source, position, + XawstWhiteSpace, XawsdLeft, 1, True); + } + if (position <= left + ctx->text.left_column) + position = tmp; + if (position > left && position - left > ctx->text.left_column + && position != right) { + text.ptr = "\n"; + text.length = 1; + CHECK_SAVE(); + if (_XawTextReplace(ctx, position, position + 1, &text)) + return (XawEditError); + right = position; + recurse = True; + force = True; + } + } + + if (force) { + if (ctx->text.justify == XawjustifyCenter) + count = ctx->text.right_column - (count - ctx->text.left_column); + else + count = ctx->text.right_column; + if (count > right - left) + count -= right - left; + else + count = 0; + } + else + count = 0; + if (count > 0) { + switch (ctx->text.justify) { + case XawjustifyLeft: + break; + case XawjustifyRight: + case XawjustifyCenter: + if (ctx->text.justify == XawjustifyCenter) { + int alnum = 0; + + if (!(count & 1)) { + XawTextSourceRead(ctx->text.source, right, &block, 1); + if ((XawTextFormat(ctx, XawFmt8Bit) + && isalnum(*(unsigned char*)block.ptr)) || + (XawTextFormat(ctx, XawFmtWide) + && iswalnum(*(wchar_t*)block.ptr))) + alnum = 1; + } + count = (count + alnum) >> 1; + } + text.ptr = XawStackAlloc(count, buf); + text.length = count; + for (i = 0; i < count; i++) + text.ptr[i] = ' '; + CHECK_SAVE(); + if (_XawTextReplace(ctx, left, left, &text)) { + XawStackFree(text.ptr, buf); + return (XawEditError); + } + XawStackFree(text.ptr, buf); + position += count; + right += count; + if (num_pos) { + for (cpos = 0; cpos < num_pos; cpos++) + if (pos[cpos] > left) + pos[cpos] += count; + } + else if (ipos > left) + ipos += count; + break; + case XawjustifyFull: + i = 0; + tmp = left; + /*CONSTCOND*/ + while (True) { + tmp = SrcScan(ctx->text.source, tmp, XawstWhiteSpace, + XawsdRight, 1, True); + if (tmp < right) + ++i; + else + break; + } + if (i) { + double inc, ii; + int bytes, steps; + + bytes = count; + inc = ii = (count + .5) / (double)i; + + steps = count; + text.ptr = XawStackAlloc(steps, buf); + for (i = 0; i < steps; i++) + text.ptr[i] = ' '; + tmp = left; + CHECK_SAVE(); + while (bytes) { + steps = 1; + while (inc + ii < 1) { + ++steps; + inc += ii; + } + tmp = SrcScan(ctx->text.source, tmp, XawstWhiteSpace, + XawsdRight, steps, True); + if (bytes > inc) + text.length = (int)inc; + else + text.length = bytes; + bytes -= text.length; + if (_XawTextReplace(ctx, tmp, tmp, &text)) { + XawStackFree(text.ptr, buf); + return (XawEditError); + } + if (num_pos) { + for (cpos = 0; cpos < num_pos; cpos++) + if (tmp <= pos[cpos]) + pos[cpos] += text.length; + } + else if (tmp <= ipos) + ipos += text.length; + inc -= (int)inc; + inc += ii; + } + position += count; + right += count; + XawStackFree(text.ptr, buf); + } + break; + } + } + + if (!num_pos) + ctx->text.insertPos = XawMin(ipos, ctx->text.lastPos); + + return (recurse ? DoFormatText(ctx, position + 1, + ctx->text.justify != XawjustifyFull + && (force2 || paragraph), + ++level, save, pos, num_pos, paragraph) + : XawEditDone); +} +#undef CHECK_SAVE + +/*ARGSUSED*/ +static void +Indent(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + TextSrcObject src = (TextSrcObject)ctx->text.source; + XawTextPosition from, to, tmp, end = 0, *pos, *posbuf[32]; + char buf[32]; + XawTextBlock text; + int i, spaces = MULT(ctx); + char *lbuf = NULL, *rbuf; + unsigned llen = 0, rlen, size; + Bool undo = src->textSrc.enable_undo && src->textSrc.undo_state == False; + Bool format = ctx->text.auto_fill + && ctx->text.left_column < ctx->text.right_column; + + text.firstPos = 0; + text.format = XawFmt8Bit; + text.ptr = ""; + + StartAction(ctx, event); + + pos = XawStackAlloc(sizeof(XawTextPosition) * src->textSrc.num_text, posbuf); + for (i = 0; i < src->textSrc.num_text; i++) + pos[i] = ((TextWidget)src->textSrc.text[i])->text.insertPos; + + if (!GetBlockBoundaries(ctx, &from, &to)) { + EndAction(ctx); + XawStackFree(pos, posbuf); + return; + } + + if (undo) { + llen = to - from; + end = ctx->text.lastPos; + lbuf = _XawTextGetText(ctx, from, to); + src->textSrc.undo_state = True; + } + + tmp = ctx->text.lastPos; + if (!Untabify(ctx, from, to, pos, src->textSrc.num_text, NULL)) { + XBell(XtDisplay(ctx), 0); + EndAction(ctx); + XawStackFree(pos, posbuf); + if (undo) { + src->textSrc.undo_state = True; + XtFree(lbuf); + } + return; + } + to += ctx->text.lastPos - tmp; + + tmp = from; + + if (spaces > 0) { + text.ptr = XawStackAlloc(spaces, buf); + for (i = 0; i < spaces; i++) + text.ptr[i] = ' '; + + text.length = spaces; + while (tmp < to) { + _XawTextReplace(ctx, tmp, tmp, &text); + + for (i = 0; i < src->textSrc.num_text; i++) + if (tmp < pos[i]) + pos[i] += spaces; + + to += spaces; + tmp = SrcScan(ctx->text.source, tmp, XawstEOL, XawsdRight, 1, True); + } + XawStackFree(text.ptr, buf); + } + else { + int min = 32767; + + text.length = 0; + tmp = from; + + /* find the amount of spaces to cut */ + while (tmp < to) { + (void)BlankLine(w, tmp, &i); + if (i < min) + min = i; + tmp = SrcScan(ctx->text.source, tmp, XawstEOL, XawsdRight, 1, True); + } + spaces = XawMin(-spaces, min); + + /* cut the spaces */ + tmp = from; + while (tmp < to) { + _XawTextReplace(ctx, tmp, tmp + spaces, &text); + + for (i = 0; i < src->textSrc.num_text; i++) + if (tmp < pos[i]) { + if (tmp + spaces < pos[i]) + pos[i] -= spaces; + else + pos[i] = tmp; + } + + to -= spaces; + tmp = SrcScan(ctx->text.source, tmp, XawstEOL, XawsdRight, 1, True); + } + } + + if (!format) + Tabify(ctx, from, to, pos, src->textSrc.num_text, NULL); + + if (undo) { + rlen = llen + (ctx->text.lastPos - end); + rbuf = _XawTextGetText(ctx, from, from + rlen); + + text.format = _XawTextFormat(ctx); + size = XawTextFormat(ctx, XawFmtWide) ? sizeof(wchar_t) : sizeof(char); + if (llen != rlen || memcmp(lbuf, rbuf, llen * size)) { + text.ptr = lbuf; + text.length = llen; + _XawTextReplace(ctx, from, from + rlen, &text); + + src->textSrc.undo_state = False; + text.ptr = rbuf; + text.length = rlen; + _XawTextReplace(ctx, from, from + llen, &text); + } + else + src->textSrc.undo_state = False; + XtFree(lbuf); + XtFree(rbuf); + } + + for (i = 0; i < src->textSrc.num_text; i++) { + TextWidget tw = (TextWidget)src->textSrc.text[i]; + + tw->text.insertPos = XawMin(XawMax(0, pos[i]), tw->text.lastPos); + } + XawStackFree(pos, posbuf); + ctx->text.showposition = True; + + EndAction(ctx); +} + +/*ARGSUSED*/ +static void +ToggleOverwrite(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + + ctx->text.overwrite = !ctx->text.overwrite; + + /* call information callback */ + _XawTextSetLineAndColumnNumber(ctx, True); +} +#endif /* OLDXAW */ + +/* + * Insertion Routines + */ +static int +InsertNewLineAndBackupInternal(TextWidget ctx) +{ + int count, error = XawEditDone, mult = MULT(ctx); +#ifndef OLDXAW + XawTextPosition position; +#endif + XawTextBlock text; + char buf[32]; + + if (mult < 0) { + ctx->text.mult = 1; + return (XawEditError); + } + + text.format = _XawTextFormat(ctx); + text.length = mult; + text.firstPos = 0; + + if (text.format == XawFmtWide) { + wchar_t *wptr; + + text.ptr = XawStackAlloc(sizeof(wchar_t) * mult, buf); + wptr = (wchar_t *)text.ptr; + for (count = 0; count < mult; count++) + wptr[count] = _Xaw_atowc(XawLF); + } + else { + text.ptr = XawStackAlloc(sizeof(char) * mult, buf); + for (count = 0; count < mult; count++) + text.ptr[count] = XawLF; + } + +#ifndef OLDXAW + position = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstEOL, XawsdLeft, 1, False); +#endif + if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) { + XBell( XtDisplay(ctx), 50); + error = XawEditError; + } + else { + ctx->text.showposition = TRUE; + ctx->text.insertPos += text.length; + } + + XawStackFree(text.ptr, buf); + +#ifndef OLDXAW + if (ctx->text.auto_fill && error == XawEditDone) + (void)FormatText(ctx, position, ctx->text.justify != XawjustifyFull, + NULL, 0); +#endif + + return (error); +} + +/*ARGSUSED*/ +static void +InsertNewLineAndBackup(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + XawTextPosition insertPos = ctx->text.insertPos; + + StartAction((TextWidget)w, event); + (void)InsertNewLineAndBackupInternal(ctx); + ctx->text.insertPos = SrcScan(ctx->text.source, insertPos, XawstEOL, + XawsdRight, 1, False); + EndAction((TextWidget)w); +} + +static int +LocalInsertNewLine(TextWidget ctx, XEvent *event) +{ + int error; + + StartAction(ctx, event); + error = InsertNewLineAndBackupInternal(ctx); + ctx->text.from_left = -1; + EndAction(ctx); + + return (error); +} + +/*ARGSUSED*/ +static void +InsertNewLine(Widget w, XEvent *event, String *p, Cardinal *n) +{ + (void)LocalInsertNewLine((TextWidget)w, event); +} + +/*ARGSUSED*/ +static void +InsertNewLineAndIndent(Widget w, XEvent *event, String *p, Cardinal *n) +{ + XawTextBlock text; + XawTextPosition pos1; + int length; + TextWidget ctx = (TextWidget)w; + String line_to_ip; + + StartAction(ctx, event); + pos1 = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstEOL, XawsdLeft, 1, False); + + line_to_ip = _XawTextGetText(ctx, pos1, ctx->text.insertPos); + + text.format = _XawTextFormat(ctx); + text.firstPos = 0; + + if (text.format == XawFmtWide) { + wchar_t *ptr; + + text.ptr = XtMalloc((2 + wcslen((wchar_t*)line_to_ip)) + * sizeof(wchar_t)); + ptr = (wchar_t*)text.ptr; + ptr[0] = _Xaw_atowc(XawLF); + wcscpy((wchar_t*)++ptr, (wchar_t*)line_to_ip); + + length = wcslen((wchar_t*)text.ptr); + while (length && (iswspace(*ptr) || *ptr == _Xaw_atowc(XawTAB))) + ptr++, length--; + *ptr = (wchar_t)0; + text.length = wcslen((wchar_t*)text.ptr); + } + else { + char *ptr; + + length = strlen(line_to_ip); + text.ptr = XtMalloc((2 + length) * sizeof(char)); + ptr = text.ptr; + ptr[0] = XawLF; + strcpy(++ptr, line_to_ip); + + length++; + while (length && (isspace(*ptr) || (*ptr == XawTAB))) + ptr++, length--; + *ptr = '\0'; + text.length = strlen(text.ptr); + } + XtFree(line_to_ip); + + if (_XawTextReplace(ctx,ctx->text.insertPos, ctx->text.insertPos, &text)) { + XBell(XtDisplay(ctx), 50); + XtFree(text.ptr); + EndAction(ctx); + return; + } + + XtFree(text.ptr); + ctx->text.from_left = -1; + ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.old_insert, + XawstPositions, XawsdRight, text.length, True); + EndAction(ctx); +} + +/* + * Selection Routines + */ +static void +SelectWord(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + XawTextPosition l, r; + + StartAction(ctx, event); + l = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstWhiteSpace, XawsdLeft, 1, False); + r = SrcScan(ctx->text.source, l, XawstWhiteSpace, XawsdRight, 1, False); + _XawTextSetSelection(ctx, l, r, params, *num_params); + EndAction(ctx); +} + +static void +SelectAll(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + + StartAction(ctx, event); + _XawTextSetSelection(ctx,zeroPosition,ctx->text.lastPos,params,*num_params); + EndAction(ctx); +} + +static void +ModifySelection(TextWidget ctx, XEvent *event, + XawTextSelectionMode mode, + XawTextSelectionAction action, + String *params, Cardinal *num_params) +{ +#ifndef OLDXAW + int old_y = ctx->text.ev_y; +#endif + + StartAction(ctx, event); + NotePosition(ctx, event); + +#ifndef OLDXAW + if (event->type == MotionNotify) { + if (ctx->text.ev_y <= ctx->text.margin.top) { + if (old_y >= ctx->text.ev_y) + XawTextScroll(ctx, -1, 0); + } + else if (ctx->text.ev_y >= XtHeight(ctx) - ctx->text.margin.bottom) { + if (old_y <= ctx->text.ev_y + && !IsPositionVisible(ctx, ctx->text.lastPos)) + XawTextScroll(ctx, 1, 0); + } + } +#endif + ctx->text.from_left = -1; + _XawTextAlterSelection(ctx, mode, action, params, num_params); + + EndAction(ctx); +} + +static void +SelectStart(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + +#ifndef OLDXAW + if (!ctx->text.selection_state) { + ctx->text.selection_state = True; +#endif + ModifySelection(ctx, event, + XawsmTextSelect, XawactionStart, params, num_params); +#ifndef OLDXAW + } +#endif +} + +static void +SelectAdjust(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + +#ifndef OLDXAW + if (ctx->text.selection_state) +#endif + ModifySelection(ctx, event, + XawsmTextSelect, XawactionAdjust, params, num_params); +} + +static void +SelectEnd(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + +#ifndef OLDXAW + if (ctx->text.selection_state) { + ctx->text.selection_state = False; +#endif + ModifySelection(ctx, event, + XawsmTextSelect, XawactionEnd, params, num_params); +#ifndef OLDXAW + } +#endif +} + +static void +ExtendStart(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + +#ifndef OLDXAW + if (!ctx->text.selection_state) { + ctx->text.selection_state = True; +#endif + ModifySelection(ctx, event, + XawsmTextExtend, XawactionStart, params, num_params); +#ifndef OLDXAW + } +#endif +} + +static void +ExtendAdjust(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + +#ifndef OLDXAW + if (ctx->text.selection_state) +#endif + ModifySelection(ctx, event, + XawsmTextExtend, XawactionAdjust, params, num_params); +} + +static void +ExtendEnd(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + +#ifndef OLDXAW + if (ctx->text.selection_state) { + ctx->text.selection_state = False; +#endif + ModifySelection(ctx, event, + XawsmTextExtend, XawactionEnd, params, num_params); +#ifndef OLDXAW + } +#endif +} + +static void +SelectSave(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + int num_atoms; + Atom *sel; + Display *dpy = XtDisplay(w); + Atom selections[256]; + + StartAction((TextWidget)w, event); + num_atoms = *num_params; + if (num_atoms > 256) + num_atoms = 256; + for (sel=selections; --num_atoms >= 0; sel++, params++) + *sel = XInternAtom(dpy, *params, False); + num_atoms = *num_params; + _XawTextSaltAwaySelection((TextWidget)w, selections, num_atoms); + EndAction((TextWidget)w); +} + +/* + * Misc. Routines + */ +/*ARGSUSED*/ +static void +SetKeyboardFocus(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + Widget shell, parent; + + shell = parent = w; + while (parent) { + if (XtIsShell(shell = parent)) + break; + parent = XtParent(parent); + } + XtSetKeyboardFocus(shell, w); +} + +/*ARGSUSED*/ +static void +RedrawDisplay(Widget w, XEvent *event, String *p, Cardinal *n) +{ + StartAction((TextWidget)w, event); + _XawTextClearAndCenterDisplay((TextWidget)w); + EndAction((TextWidget)w); +} + +/* This is kind of a hack, but, only one text widget can have focus at + * a time on one display. There is a problem in the implementation of the + * text widget, the scrollbars can not be adressed via editres, since they + * are not children of a subclass of composite. + * The focus variable is required to make sure only one text window will + * show a block cursor at one time. + */ +struct _focus { Display *display; Widget widget; }; +static struct _focus *focus; +static Cardinal num_focus; + +/*ARGSUSED*/ +static void +DestroyFocusCallback(Widget w, XtPointer user_data, XtPointer call_data) +{ + struct _focus *f = (struct _focus*)(user_data); + + if (f->widget == w) + f->widget = NULL; +} + +/*ARGSUSED*/ +static void +TextFocusIn(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + Bool display_caret = ctx->text.display_caret; + int i; + + if (event->xfocus.detail == NotifyPointer) + return; + + if (event->xfocus.send_event) { + Window root, child; + int rootx, rooty, x, y; + unsigned int mask; + + if (ctx->text.hasfocus) + return; + + if (XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, + &rootx, &rooty, &x, &y, &mask)) { + if (child) + return; + } + } + + /* Let the input method know focus has arrived. */ + _XawImSetFocusValues(w, NULL, 0); + + if (display_caret) + StartAction(ctx, event); + ctx->text.hasfocus = TRUE; + if (display_caret) + EndAction(ctx); + + for (i = 0; i < num_focus; i++) + if (focus[i].display == XtDisplay(w)) + break; + if (i >= num_focus) { + focus = (struct _focus*) + XtRealloc((XtPointer)focus, sizeof(struct _focus) * (num_focus + 1)); + i = num_focus; + focus[i].widget = NULL; + focus[i].display = XtDisplay(w); + num_focus++; + } + if (focus[i].widget != w) { + Widget old = focus[i].widget; + + focus[i].widget = w; + if (old != NULL) { + TextFocusOut(old, event, p, n); + /* TextFocusOut may set it to NULL */ + focus[i].widget = w; + } + XtAddCallback(w, XtNdestroyCallback, + DestroyFocusCallback, (XtPointer)&focus[i]); + } +} + +/*ARGSUSED*/ +static void +TextFocusOut(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + Bool display_caret = ctx->text.display_caret; + Widget shell; + Window window; + int i, revert; + + shell = w; + while (shell) { + if (XtIsShell(shell)) + break; + shell = XtParent(shell); + } + + for (i = 0; i < num_focus; i++) + if (focus[i].display == XtDisplay(w)) + break; + XGetInputFocus(XtDisplay(w), &window, &revert); + if ((XtWindow(shell) == window && + (i < num_focus && focus[i].widget == w)) + || event->xfocus.detail == NotifyPointer) + return; + + if (i < num_focus && focus[i].widget) { + XtRemoveCallback(focus[i].widget, XtNdestroyCallback, + DestroyFocusCallback, (XtPointer)&focus[i]); + focus[i].widget = NULL; + } + + /* Let the input method know focus has left.*/ + _XawImUnsetFocus(w); + + if (display_caret) + StartAction(ctx, event); + ctx->text.hasfocus = FALSE; + if (display_caret) + EndAction(ctx); +} + +/*ARGSUSED*/ +static void +TextEnterWindow(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + + if ((event->xcrossing.detail != NotifyInferior) && event->xcrossing.focus + && !ctx->text.hasfocus) + _XawImSetFocusValues(w, NULL, 0); +} + +/*ARGSUSED*/ +static void +TextLeaveWindow(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + + if ((event->xcrossing.detail != NotifyInferior) && event->xcrossing.focus + && !ctx->text.hasfocus) + _XawImUnsetFocus(w); +} + +/* + * Function: + * AutoFill + * Arguments: ctx - The text widget. + * + * Description: + * Breaks the line at the previous word boundry when + * called inside InsertChar. + */ +static void +AutoFill(TextWidget ctx) +{ + int width, height, x, line_num, max_width; + XawTextPosition ret_pos; + XawTextBlock text; + XRectangle cursor; + wchar_t wc_buf[2]; + + for (line_num = 0; line_num < ctx->text.lt.lines ; line_num++) + if (ctx->text.lt.info[line_num].position >= ctx->text.insertPos) + break; + if (line_num) + line_num--; /* backup a line. */ + + XawTextSinkGetCursorBounds(ctx->text.sink, &cursor); + max_width = Max(0, (int)XtWidth(ctx) - RHMargins(ctx) - cursor.width); + + x = ctx->text.r_margin.left; + XawTextSinkFindPosition(ctx->text.sink, ctx->text.lt.info[line_num].position, + x, max_width, True, &ret_pos, + &width, &height); + + if (ret_pos <= ctx->text.lt.info[line_num].position + || ret_pos >= ctx->text.insertPos || ret_pos < 1) + return; + + XawTextSourceRead(ctx->text.source, ret_pos - 1, &text, 1); + + if (XawTextFormat(ctx, XawFmtWide)) { + wc_buf[0] = *(wchar_t *)text.ptr; + if (wc_buf[0] != _Xaw_atowc(XawSP) && wc_buf[0] != _Xaw_atowc(XawTAB)) + /* Only eats white spaces */ + return; + + text.format = XawFmtWide; + text.ptr = (char *)wc_buf; + wc_buf[0] = _Xaw_atowc(XawLF); + wc_buf[1] = 0; + } + else { + if (text.ptr[0] != XawSP && text.ptr[0] != XawTAB) + /* Only eats white spaces */ + return; + + text.format = XawFmt8Bit; + text.ptr = "\n"; + } + text.length = 1; + text.firstPos = 0; + + if (_XawTextReplace(ctx, ret_pos - 1, ret_pos, &text)) + XBell(XtDisplay((Widget)ctx), 0); + + if (++ctx->text.insertPos > ctx->text.lastPos) + ctx->text.insertPos = ctx->text.lastPos; +} + +/*ARGSUSED*/ +static void +InsertChar(Widget w, XEvent *event, String *p, Cardinal *n) +{ + TextWidget ctx = (TextWidget)w; + char *ptr, strbuf[128], ptrbuf[512]; + int count, error, mult = MULT(ctx); + KeySym keysym; + XawTextBlock text; +#ifndef OLDXAW + Bool format = False; +#endif + XawTextPosition from, to; + + if (XtIsSubclass (ctx->text.source, (WidgetClass) multiSrcObjectClass)) + text.length = _XawImWcLookupString(w, &event->xkey, (wchar_t*)strbuf, + sizeof(strbuf), &keysym); + else + text.length = _XawLookupString(w, (XKeyEvent*)event, strbuf, + sizeof(strbuf), &keysym); + + if (text.length == 0) + return; + + if (mult < 0) { + ctx->text.mult = 1; + return; + } + + text.format = _XawTextFormat(ctx); + if (text.format == XawFmtWide) { + text.ptr = ptr = XawStackAlloc(sizeof(wchar_t) * text.length + * mult, ptrbuf); + for (count = 0; count < mult; count++) { + memcpy((char*)ptr, (char *)strbuf, sizeof(wchar_t) * text.length); + ptr += sizeof(wchar_t) * text.length; + } +#ifndef OLDXAW + if (mult == 1) + format = ctx->text.left_column < ctx->text.right_column; +#endif + } + else { /* == XawFmt8Bit */ + text.ptr = ptr = XawStackAlloc(text.length * mult, ptrbuf); + for (count = 0; count < mult; count++) { + strncpy(ptr, strbuf, text.length); + ptr += text.length; + } +#ifndef OLDXAW + if (mult == 1) + format = ctx->text.left_column < ctx->text.right_column; +#endif + } + + text.length = text.length * mult; + text.firstPos = 0; + + StartAction(ctx, event); +#ifndef OLDXAW + if (mult == 1) + _XawSourceSetUndoMerge((TextSrcObject)ctx->text.source, True); +#endif + + from = ctx->text.insertPos; +#ifndef OLDXAW + if (ctx->text.overwrite) { + XawTextPosition tmp; + + to = from + mult; + tmp = SrcScan(ctx->text.source, from, XawstEOL, XawsdRight, 1, False); + if (to > tmp) + to = tmp; + } + else +#endif + to = from; + + error = _XawTextReplace(ctx, from , to, &text); + + if (error == XawEditDone) { + ctx->text.from_left = -1; + ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.old_insert, + XawstPositions, XawsdRight, + text.length, True); + if (ctx->text.auto_fill) { +#ifndef OLDXAW + if (format) + (void)FormatText(ctx, SrcScan(ctx->text.source, + ctx->text.insertPos, XawstEOL, + XawsdLeft, 1, False), False, + NULL, 0); + else +#endif + AutoFill(ctx); + } + } + else + XBell(XtDisplay(ctx), 50); + + XawStackFree(text.ptr, ptrbuf); + EndAction(ctx); + + if (error == XawEditDone && text.format == XawFmt8Bit && text.length == 1 + && (text.ptr[0] == ')' || text.ptr[0] == ']' || text.ptr[0] == '}') + && ctx->text.display_caret) { + static struct timeval tmval = {0, 500000}; + fd_set fds; + Widget source = ctx->text.source; + XawTextPosition insertPos = ctx->text.insertPos, pos, tmp, last; + char left, right = text.ptr[0]; + int level = 0; + XtAppContext app_context = XtWidgetToApplicationContext(w); + + left = right == ')' ? '(' : right == ']' ? '[' : '{'; + + last = insertPos - 1; + do { + text.ptr[0] = left; + pos = XawTextSourceSearch(source, last, XawsdLeft, &text); + if (pos == XawTextSearchError || !IsPositionVisible(ctx, pos)) + return; + text.ptr[0] = right; + tmp = pos; + do { + tmp = XawTextSourceSearch(source, tmp, XawsdRight, &text); + if (tmp == XawTextSearchError) + return; + if (tmp <= last) + ++level; + } while (++tmp <= last); + --level; + last = pos; + } while (level); + + StartAction(ctx, NULL); +#ifndef OLDXAW + _XawSourceSetUndoMerge((TextSrcObject)ctx->text.source, True); +#endif + ctx->text.insertPos = pos; + EndAction(ctx); + + XSync(XtDisplay(w), False); + while (XtAppPending(app_context) & XtIMXEvent) { + XEvent ev; + if (! XtAppPeekEvent(app_context, &ev)) + break; + if (ev.type == KeyPress || ev.type == ButtonPress) + break; + XtAppProcessEvent(app_context, XtIMXEvent); + } + FD_ZERO(&fds); + FD_SET(ConnectionNumber(XtDisplay(w)), &fds); + (void)select(FD_SETSIZE, &fds, NULL, NULL, &tmval); + if (tmval.tv_usec != 500000) + usleep(40000); + + StartAction(ctx, NULL); +#ifndef OLDXAW + _XawSourceSetUndoMerge((TextSrcObject)ctx->text.source, True); +#endif + ctx->text.insertPos = insertPos; + EndAction(ctx); + } +} + +/* IfHexConvertHexElseReturnParam() - called by InsertString + * + * i18n requires the ability to specify multiple characters in a hexa- + * decimal string at once. Since Insert was already too long, I made + * this a seperate routine. + * + * A legal hex string in MBNF: '0' 'x' ( HEX-DIGIT HEX-DIGIT )+ '\0' + * + * WHEN: the passed param is a legal hex string + * RETURNS: a pointer to that converted, null terminated hex string; + * len_return holds the character count of conversion result + * + * WHEN: the passed param is not a legal hex string: + * RETURNS: the parameter passed; + * len_return holds the char count of param. + * + * NOTE: In neither case will there be strings to free. */ +static char * +IfHexConvertHexElseReturnParam(char *param, int *len_return) +{ + char *p; /* steps through param char by char */ + char c; /* holds the character pointed to by p */ + int ind; /* steps through hexval buffer char by char */ + static char hexval[XawTextActionMaxHexChars]; + Boolean first_digit; + + /* reject if it doesn't begin with 0x and at least one more character. */ + if ((param[0] != '0') || (param[1] != 'x') || (param[2] == '\0')) { + *len_return = strlen(param); + return(param); + } + + /* Skip the 0x; go character by character shifting and adding. */ + first_digit = True; + ind = 0; + hexval[ind] = '\0'; + + for (p = param+2; (c = *p) != '\0'; p++) { + hexval[ind] *= 16; + if (c >= '0' && c <= '9') + hexval[ind] += c - '0'; + else if (c >= 'a' && c <= 'f') + hexval[ind] += c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + hexval[ind] += c - 'A' + 10; + else + break; + + /* If we didn't break in preceding line, it was a good hex char. */ + if (first_digit) + first_digit = False; + else { + first_digit = True; + if (++ind < XawTextActionMaxHexChars) + hexval[ind] = '\0'; + else { + *len_return = strlen(param); + return(param); + } + } + } + + /* We quit the above loop becasue we hit a non hex. If that char is \0... */ + if ((c == '\0') && first_digit) { + *len_return = strlen(hexval); + return (hexval); /* ...it was a legal hex string, so return it */ + } + + /* Else, there were non-hex chars or odd digit count, so... */ + + *len_return = strlen(param); + return (param); /* ...return the verbatim string. */ +} + +/* InsertString() - action + * + * Mostly rewritten for R6 i18n. + * + * Each parameter, in turn, will be insert at the inputPos + * and the inputPos advances to the insertion's end. + * + * The exception is that parameters composed of the two + * characters 0x, followed only by an even number of + * hexadecimal digits will be converted to characters */ +/*ARGSUSED*/ +static void +InsertString(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + XtAppContext app_con = XtWidgetToApplicationContext(w); + XawTextBlock text; + int i; + + text.firstPos = 0; + text.format = _XawTextFormat(ctx); + + StartAction(ctx, event); + for (i = *num_params; i; i--, params++) { /* DO FOR EACH PARAMETER */ + text.ptr = IfHexConvertHexElseReturnParam(*params, &text.length); + + if (text.length == 0) + continue; + + if (XawTextFormat(ctx, XawFmtWide)) { /* convert to WC */ + int temp_len; + + text.ptr = (char*)_XawTextMBToWC(XtDisplay(w), text.ptr, + &text.length); + + if (text.ptr == NULL) { /* conversion error */ + XtAppWarningMsg(app_con, + "insertString", "textAction", "XawError", + "insert-string()'s parameter contents " + "not legal in this locale.", + NULL, NULL); + ParameterError(w, *params); + continue; + } + + /* Double check that the new input is legal: try to convert to MB. */ + + temp_len = text.length; /* _XawTextWCToMB's 3rd arg is in_out */ + if (_XawTextWCToMB(XtDisplay(w), (wchar_t*)text.ptr, &temp_len) + == NULL) { + XtAppWarningMsg( app_con, + "insertString", "textAction", "XawError", + "insert-string()'s parameter contents " + "not legal in this locale.", + NULL, NULL); + ParameterError(w, *params); + continue; + } + } /* convert to WC */ + + if (_XawTextReplace(ctx, ctx->text.insertPos, + ctx->text.insertPos, &text)) { + XBell(XtDisplay(ctx), 50); + EndAction(ctx); + return; + } + + ctx->text.from_left = -1; + /* Advance insertPos to the end of the string we just inserted. */ + ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.old_insert, + XawstPositions, XawsdRight, text.length, + True); + + } /* DO FOR EACH PARAMETER */ + + EndAction(ctx); +} + +/* DisplayCaret() - action + * + * The parameter list should contain one boolean value. If the + * argument is true, the cursor will be displayed. If false, not. + * + * The exception is that EnterNotify and LeaveNotify events may + * have a second argument, "always". If they do not, the cursor + * is only affected if the focus member of the event is true. */ +static void +DisplayCaret(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + Bool display_caret = True; + + if ((event->type == EnterNotify || event->type == LeaveNotify) + && ((*num_params >= 2) && (strcmp(params[1], "always") == 0)) + && (!event->xcrossing.focus)) + return; + + if (*num_params > 0) { /* default arg is "True" */ + XrmValue from, to; + from.size = strlen(from.addr = params[0]); + XtConvert(w, XtRString, &from, XtRBoolean, &to); + + if (to.addr != NULL) + display_caret = *(Boolean*)to.addr; + if (ctx->text.display_caret == display_caret) + return; + } + StartAction(ctx, event); + ctx->text.display_caret = display_caret; + EndAction(ctx); +} + +#ifndef OLDXAW +static void +Numeric(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + + if (ctx->text.numeric) { + long mult = ctx->text.mult; + + if (*num_params != 1 || strlen(params[0]) != 1 + || (!isdigit(params[0][0]) + && (params[0][0] != '-' || mult != 0))) { + char err_buf[256]; + + if (event && (event->type == KeyPress || event->type == KeyRelease) + && params[0][0] == '-') { + InsertChar(w, event, params, num_params); + return; + } + snprintf(err_buf, sizeof(err_buf), + "numeric: Invalid argument%s'%s'", + *num_params ? ", " : "", + *num_params ? params[0] : ""); + XtAppWarning(XtWidgetToApplicationContext(w), err_buf); + ctx->text.numeric = False; + ctx->text.mult = 1; + return; + } + if (params[0][0] == '-') { + ctx->text.mult = 32767; + return; + } + else if (mult == 32767) { + mult = ctx->text.mult = - (params[0][0] - '0'); + return; + } + else { + mult = mult * 10 + (params[0][0] - '0') * (mult < 0 ? -1 : 1); + ctx->text.mult = ctx->text.mult * 10 + (params[0][0] - '0') * + (mult < 0 ? -1 : 1); + } + if (mult != ctx->text.mult || mult >= 32767) { /* checks for overflow */ + XBell(XtDisplay(w), 0); + ctx->text.mult = 1; + ctx->text.numeric = False; + return; + } + } + else + InsertChar(w, event, params, num_params); +} + +/*ARGSUSED*/ +static void +KeyboardReset(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + + ctx->text.numeric = False; + ctx->text.mult = 1; + + (void)_XawTextSrcToggleUndo((TextSrcObject)ctx->text.source); + + if (ctx->text.kill_ring_ptr) { + --ctx->text.kill_ring_ptr->refcount; + ctx->text.kill_ring_ptr = NULL; + } + ctx->text.kill_ring = 0; + + XBell(XtDisplay(w), 0); +} +#endif /* OLDXAW */ + +/* Multiply() - action + * + * The parameter list may contain either a number or the string 'Reset'. + * + * A number will multiply the current multiplication factor by that number. + * Many of the text widget actions will will perform n actions, where n is + * the multiplication factor. + * + * The string reset will reset the mutiplication factor to 1. */ +/*ARGSUSED*/ +static void +Multiply(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + int mult; + + if (*num_params != 1) { + XtAppError(XtWidgetToApplicationContext(w), + "Xaw Text Widget: multiply() takes exactly one argument."); + XBell(XtDisplay(w), 0); + return; + } + + if ((params[0][0] == 'r') || (params[0][0] == 'R')) { + XBell(XtDisplay(w), 0); +#ifndef OLDXAW + ctx->text.numeric = False; +#endif + ctx->text.mult = 1; + return; + } + +#ifndef OLDXAW + if (params[0][0] == 's' || params[0][0] == 'S') { + ctx->text.numeric = True; + ctx->text.mult = 0; + return; + } + else +#endif + if ((mult = atoi(params[0])) == 0) { + char buf[BUFSIZ]; + + snprintf(buf, sizeof(buf), + "Xaw Text Widget: multiply() argument " + "must be a number greater than zero, or 'Reset'."); + XtAppError(XtWidgetToApplicationContext(w), buf); + XBell(XtDisplay(w), 50); + return; + } + + ctx->text.mult *= mult; +} + +/* StripOutOldCRs() - called from FormRegion + * + * removes CRs in widget ctx, from from to to. + * + * RETURNS: the new ending location (we may add some characters), + * or XawReplaceError if the widget can't be written to. */ +static XawTextPosition +StripOutOldCRs(TextWidget ctx, XawTextPosition from, XawTextPosition to, + XawTextPosition *pos, int num_pos) +{ + XawTextPosition startPos, endPos, eop_begin, eop_end, temp; + Widget src = ctx->text.source; + XawTextBlock text; + char *buf; + static wchar_t wc_two_spaces[3]; + int idx; + + /* Initialize our TextBlock with two spaces. */ + text.firstPos = 0; + text.format = _XawTextFormat(ctx); + if (text.format == XawFmt8Bit) + text.ptr= " "; + else { + wc_two_spaces[0] = _Xaw_atowc(XawSP); + wc_two_spaces[1] = _Xaw_atowc(XawSP); + wc_two_spaces[2] = 0; + text.ptr = (char*)wc_two_spaces; + } + + /* Strip out CR's. */ + eop_begin = eop_end = startPos = endPos = from; + + /* CONSTCOND */ + while (TRUE) { + endPos=SrcScan(src, startPos, XawstEOL, XawsdRight, 1, False); + + temp = SrcScan(src, endPos, XawstWhiteSpace, XawsdLeft, 1, False); + temp = SrcScan(src, temp, XawstWhiteSpace, XawsdRight,1, False); + + if (temp > startPos) + endPos = temp; + + if (endPos >= to) + break; + + if (endPos >= eop_begin) { + startPos = eop_end; + eop_begin=SrcScan(src, startPos, XawstParagraph, + XawsdRight, 1,False); + eop_end = SrcScan(src, startPos, XawstParagraph, + XawsdRight, 1, True); + } + else { + XawTextPosition periodPos, next_word; + int i, len; + + periodPos = SrcScan(src, endPos, XawstPositions, + XawsdLeft, 1, True); + next_word = SrcScan(src, endPos, XawstWhiteSpace, + XawsdRight, 1, False); + + len = next_word - periodPos; + + text.length = 1; + buf = _XawTextGetText(ctx, periodPos, next_word); + if (text.format == XawFmtWide) { + if (periodPos < endPos && ((wchar_t*)buf)[0] == _Xaw_atowc('.')) + text.length++; + } + else + if (periodPos < endPos && buf[0] == '.') + text.length++; /* Put in two spaces. */ + + /* + * Remove all extra spaces. + */ + for (i = 1 ; i < len; i++) + if (text.format == XawFmtWide) { + if (!iswspace(((wchar_t*)buf)[i]) || ((periodPos + i) >= to)) + break; + } + else if (!isspace(buf[i]) || (periodPos + i) >= to) + break; + + XtFree(buf); + + to -= (i - text.length - 1); + startPos = SrcScan(src, periodPos, XawstPositions, + XawsdRight, i, True); + if (_XawTextReplace(ctx, endPos, startPos, &text) != XawEditDone) + return (XawReplaceError); + + for (idx = 0; idx < num_pos; idx++) { + if (endPos < pos[idx]) { + if (startPos < pos[idx]) + pos[idx] -= startPos - endPos; + else + pos[idx] = endPos; + pos[idx] += text.length; + } + } + + startPos -= i - text.length; + } + } + + return (to); +} + +/* InsertNewCRs() - called from FormRegion + * + * inserts new CRs for FormRegion, thus for FormParagraph action */ +static void +InsertNewCRs(TextWidget ctx, XawTextPosition from, XawTextPosition to, + XawTextPosition *pos, int num_pos) +{ + XawTextPosition startPos, endPos, space, eol; + XawTextBlock text; + int i, width, height, len, wwidth, idx; + char *buf; + static wchar_t wide_CR[2]; + + text.firstPos = 0; + text.length = 1; + text.format = _XawTextFormat(ctx); + + if (text.format == XawFmt8Bit) + text.ptr = "\n"; + else { + wide_CR[0] = _Xaw_atowc(XawLF); + wide_CR[1] = 0; + text.ptr = (char*)wide_CR; + } + + startPos = from; + + wwidth = (int)XtWidth(ctx) - (int)HMargins(ctx); + if (ctx->text.wrap != XawtextWrapNever) { + XRectangle cursor; + + XawTextSinkGetCursorBounds(ctx->text.sink, &cursor); + wwidth -= (int)cursor.width; + } + wwidth = XawMax(0, wwidth); + + /* CONSTCOND */ + while (TRUE) { + XawTextSinkFindPosition(ctx->text.sink, startPos, + (int)ctx->text.r_margin.left, wwidth, + True, &eol, &width, &height); + if (eol == startPos) + ++eol; + if (eol >= to) + break; + + eol = SrcScan(ctx->text.source, eol, XawstPositions, + XawsdLeft, 1, True); + space = SrcScan(ctx->text.source, eol, XawstWhiteSpace, + XawsdRight,1, True); + + startPos = endPos = eol; + if (eol == space) + return; + + len = (int)(space - eol); + buf = _XawTextGetText(ctx, eol, space); + for (i = 0 ; i < len ; i++) + if (text.format == XawFmtWide) { + if (!iswspace(((wchar_t*)buf)[i])) + break; + } + else if (!isspace(buf[i])) + break; + + to -= (i - 1); + endPos = SrcScan(ctx->text.source, endPos, + XawstPositions, XawsdRight, i, True); + XtFree(buf); + + if (_XawTextReplace(ctx, startPos, endPos, &text)) + return; + + for (idx = 0; idx < num_pos; idx++) { + if (startPos < pos[idx]) { + if (endPos < pos[idx]) + pos[idx] -= endPos - startPos; + else + pos[idx] = startPos; + pos[idx] += text.length; + } + } + + startPos = SrcScan(ctx->text.source, startPos, + XawstPositions, XawsdRight, 1, True); + } +} + +/* FormRegion() - called by FormParagraph + * + * oversees the work of paragraph-forming a region + * + * Return: + * XawEditDone if successful, or XawReplaceError + */ +static int +FormRegion(TextWidget ctx, XawTextPosition from, XawTextPosition to, + XawTextPosition *pos, int num_pos) +{ +#ifndef OLDXAW + Bool format = ctx->text.auto_fill + && ctx->text.left_column < ctx->text.right_column; +#endif + + if (from >= to) + return (XawEditDone); + +#ifndef OLDXAW + if (format) { + XawTextPosition len = ctx->text.lastPos; + int inc = 0; + + if (ctx->text.justify == XawjustifyLeft || + ctx->text.justify == XawjustifyFull) { + Untabify(ctx, from, to, pos, num_pos, NULL); + to += ctx->text.lastPos - len; + len = ctx->text.insertPos; + (void)BlankLine((Widget)ctx, from, &inc); + if (from + inc >= to) + return (XawEditDone); + } + if (!StripSpaces(ctx, from + inc, to, pos, num_pos, NULL)) + return (XawReplaceError); + to += ctx->text.lastPos - len; + + FormatText(ctx, from, ctx->text.justify != XawjustifyFull, pos, num_pos); + } + else { +#endif + if ((to = StripOutOldCRs(ctx, from, to, pos, num_pos)) == XawReplaceError) + return (XawReplaceError); + InsertNewCRs(ctx, from, to, pos, num_pos); +#ifndef OLDXAW + } +#endif + ctx->text.from_left = -1; + + return (XawEditDone); +} + +#ifndef OLDXAW +static Bool +BlankLine(Widget w, XawTextPosition pos, int *blanks_return) +{ + int i, blanks = 0; + XawTextBlock block; + Widget src = XawTextGetSource(w); + XawTextPosition l = SrcScan(src, pos, XawstEOL, XawsdLeft, 1, False); + XawTextPosition r = SrcScan(src, pos, XawstEOL, XawsdRight, 1, False); + + while (l < r) { + l = XawTextSourceRead(src, l, &block, r - l); + if (block.length == 0) { + if (blanks_return) + *blanks_return = blanks; + return (True); + } + if (XawTextFormat((TextWidget)w, XawFmt8Bit)) { + for (i = 0; i < block.length; i++, blanks++) + if (block.ptr[i] != ' ' && + block.ptr[i] != '\t') { + if (blanks_return) + *blanks_return = blanks; + return (block.ptr[i] == '\n'); + } + } + else if (XawTextFormat((TextWidget)w, XawFmtWide)) { + for (i = 0; i < block.length; i++, blanks++) + if (_Xaw_atowc(XawSP) != ((wchar_t*)block.ptr)[i] && + _Xaw_atowc(XawTAB) != ((wchar_t*)block.ptr)[i]) { + if (blanks_return) + *blanks_return = blanks; + return (_Xaw_atowc(XawLF) == ((wchar_t*)block.ptr)[i]); + } + } + } + + return (True); +} + +static Bool +GetBlockBoundaries(TextWidget ctx, + XawTextPosition *from_return, XawTextPosition *to_return) +{ + XawTextPosition from, to; + + if (ctx->text.auto_fill && ctx->text.left_column < ctx->text.right_column) { + if (ctx->text.s.left != ctx->text.s.right) { + from = SrcScan(ctx->text.source, + XawMin(ctx->text.s.left, ctx->text.s.right), + XawstEOL, XawsdLeft, 1, False); + to = SrcScan(ctx->text.source, + XawMax(ctx->text.s.right, ctx->text.s.right), + XawstEOL, XawsdRight, 1, False); + } + else { + XawTextBlock block; + XawTextPosition tmp; + Bool first; + + from = to = ctx->text.insertPos; + + /* find from position */ + first = True; + while (1) { + tmp = from; + from = SrcScan(ctx->text.source, from, XawstEOL, XawsdLeft, + 1 + !first, False); + XawTextSourceRead(ctx->text.source, from, &block, 1); + if (block.length == 0 || + (XawTextFormat(ctx, XawFmt8Bit) && + block.ptr[0] != ' ' && + block.ptr[0] != '\t' && + !isalnum(*(unsigned char*)block.ptr)) || + (XawTextFormat(ctx, XawFmtWide) && + _Xaw_atowc(XawSP) != *(wchar_t*)block.ptr && + _Xaw_atowc(XawTAB) != *(wchar_t*)block.ptr && + !iswalnum(*(wchar_t*)block.ptr)) || + BlankLine((Widget)ctx, from, NULL)) { + from = tmp; + break; + } + if (from == tmp && !first) + break; + first = False; + } + if (first) + return (False); + + /* find to position */ + first = True; + while (1) { + tmp = to; + to = SrcScan(ctx->text.source, to, XawstEOL, XawsdRight, + 1 + !first, False); + XawTextSourceRead(ctx->text.source, to + (to < ctx->text.lastPos), + &block, 1); + if (block.length == 0 || + (XawTextFormat(ctx, XawFmt8Bit) && + block.ptr[0] != ' ' && + block.ptr[0] != '\t' && + !isalnum(*(unsigned char*)block.ptr)) || + (XawTextFormat(ctx, XawFmtWide) && + _Xaw_atowc(XawSP) != *(wchar_t*)block.ptr && + _Xaw_atowc(XawTAB) != *(wchar_t*)block.ptr && + !iswalnum(*(wchar_t*)block.ptr)) || + BlankLine((Widget)ctx, to, NULL)) + break; + if (to == tmp && !first) + break; + first = False; + } + } + } + else { + from = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, + XawsdLeft, 1, False); + if (BlankLine((Widget)ctx, from, NULL)) + return (False); + from = SrcScan(ctx->text.source, from, XawstParagraph, + XawsdLeft, 1, False); + if (BlankLine((Widget)ctx, from, NULL)) + from = SrcScan(ctx->text.source, from, XawstEOL, + XawsdRight, 1, True); + to = SrcScan(ctx->text.source, from, XawstParagraph, + XawsdRight, 1, False); + } + + if (from < to) { + *from_return = from; + *to_return = to; + return (True); + } + + return (False); +} +#endif /* OLDXAW */ + +/* FormParagraph() - action + * + * removes and reinserts CRs to maximize line length without clipping */ +/*ARGSUSED*/ +static void +FormParagraph(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + XawTextPosition from, to, buf[32], *pos; +#ifndef OLDXAW + XawTextPosition endPos = 0; + char *lbuf = NULL, *rbuf; + TextSrcObject src = (TextSrcObject)ctx->text.source; + Cardinal i; + Bool undo = src->textSrc.enable_undo && src->textSrc.undo_state == False; +#endif + + StartAction(ctx, event); + +#ifndef OLDXAW + pos = XawStackAlloc(sizeof(XawTextPosition) * src->textSrc.num_text, buf); + for (i = 0; i < src->textSrc.num_text; i++) + pos[i] = ((TextWidget)src->textSrc.text[i])->text.old_insert; +#else + pos = buf; + *pos = ctx->text.old_insert; +#endif + +#ifndef OLDXAW + if (!GetBlockBoundaries(ctx, &from, &to)) { + EndAction(ctx); + XawStackFree(pos, buf); + return; + } + + if (undo) { + src->textSrc.undo_state = True; + lbuf = _XawTextGetText(ctx, from, to); + endPos = ctx->text.lastPos; + } + + if (FormRegion(ctx, from, to, pos, src->textSrc.num_text) == XawReplaceError) { + XawStackFree(pos, buf); + pos = buf; +#else + from = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstParagraph, XawsdLeft, 1, False); + to = SrcScan(ctx->text.source, from, + XawstParagraph, XawsdRight, 1, False); + + if (FormRegion(ctx, from, to, pos, 1) == XawReplaceError) { +#endif + XBell(XtDisplay(w), 0); +#ifndef OLDXAW + if (undo) { + src->textSrc.undo_state = False; + XtFree(lbuf); + } +#endif + } +#ifndef OLDXAW + else if (undo) { + /* makes the form-paragraph only one undo/redo step */ + unsigned llen, rlen, size; + XawTextBlock block; + + llen = to - from; + rlen = llen + (ctx->text.lastPos - endPos); + + block.firstPos = 0; + block.format = _XawTextFormat(ctx); + + rbuf = _XawTextGetText(ctx, from, from + rlen); + + size = XawTextFormat(ctx, XawFmtWide) ? sizeof(wchar_t) : sizeof(char); + if (llen != rlen || memcmp(lbuf, rbuf, llen * size)) { + block.ptr = lbuf; + block.length = llen; + _XawTextReplace(ctx, from, from + rlen, &block); + + src->textSrc.undo_state = False; + block.ptr = rbuf; + block.length = rlen; + _XawTextReplace(ctx, from, from + llen, &block); + } + else + src->textSrc.undo_state = False; + XtFree(lbuf); + XtFree(rbuf); + } + + for (i = 0; i < src->textSrc.num_text; i++) { + TextWidget tw = (TextWidget)src->textSrc.text[i]; + + tw->text.old_insert = tw->text.insertPos = pos[i]; + _XawTextBuildLineTable(tw, SrcScan((Widget)src, tw->text.lt.top, XawstEOL, + XawsdLeft, 1, False), False); + tw->text.clear_to_eol = True; + } + XawStackFree(pos, buf); +#else + ctx->text.old_insert = ctx->text.insertPos = *pos; + _XawTextBuildLineTable(ctx, SrcScan(ctx->text.source, ctx->text.lt.top, + XawstEOL, XawsdLeft, 1, False), False); + ctx->text.clear_to_eol = True; +#endif + ctx->text.showposition = True; + + EndAction(ctx); +} + +/* TransposeCharacters() - action + * + * Swaps the character to the left of the mark + * with the character to the right of the mark */ +/*ARGSUSED*/ +static void +TransposeCharacters(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + XawTextPosition start, end; + XawTextBlock text; + char *buf; + int i, mult = MULT(ctx); + + if (mult < 0) { + ctx->text.mult = 1; + return; + } + + StartAction(ctx, event); + + /* Get bounds. */ + + start = SrcScan(ctx->text.source, ctx->text.insertPos, XawstPositions, + XawsdLeft, 1, True); + end = SrcScan(ctx->text.source, ctx->text.insertPos, XawstPositions, + XawsdRight, mult, True); + + /* Make sure we aren't at the very beginning or end of the buffer. */ + + if (start == ctx->text.insertPos || end == ctx->text.insertPos) { + XBell(XtDisplay(w), 0); /* complain. */ + EndAction(ctx); + return; + } + + ctx->text.from_left = -1; + ctx->text.insertPos = end; + + text.firstPos = 0; + text.format = _XawTextFormat(ctx); + + /* Retrieve text and swap the characters. */ + if (text.format == XawFmtWide) { + wchar_t wc; + wchar_t *wbuf; + + wbuf = (wchar_t*)_XawTextGetText(ctx, start, end); + text.length = wcslen(wbuf); + wc = wbuf[0]; + for (i = 1; i < text.length; i++) + wbuf[i - 1] = wbuf[i]; + wbuf[i - 1] = wc; + buf = (char*)wbuf; /* so that it gets assigned and freed */ + } + else { /* thus text.format == XawFmt8Bit */ + char c; + + buf = _XawTextGetText(ctx, start, end); + text.length = strlen(buf); + c = buf[0]; + for (i = 1; i < text.length; i++) + buf[i - 1] = buf[i]; + buf[i - 1] = c; + } + + text.ptr = buf; + + /* Store new text in source. */ + + if (_XawTextReplace (ctx, start, end, &text)) + XBell(XtDisplay(w), 0); + XtFree((char *)buf); + EndAction(ctx); +} + +#ifndef OLDXAW +/*ARGSUSED*/ +static void +Undo(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + int mul = MULT(ctx); + Bool toggle = False; + + if (mul < 0) { + toggle = True; + _XawTextSrcToggleUndo((TextSrcObject)ctx->text.source); + ctx->text.mult = mul = -mul; + } + + StartAction(ctx, event); + for (; mul; --mul) + if (!_XawTextSrcUndo((TextSrcObject)ctx->text.source, &ctx->text.insertPos)) + break; + ctx->text.showposition = True; + + if (toggle) + _XawTextSrcToggleUndo((TextSrcObject)ctx->text.source); + EndAction(ctx); +} +#endif + +/* NoOp() - action + * This action performs no action, and allows the user or + * application programmer to unbind a translation. + * + * Note: If the parameter list contains the string "RingBell" then + * this action will ring the bell. + */ +/*ARGSUSED*/ +static void +NoOp(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + if (*num_params != 1) + return; + + switch(params[0][0]) { + case 'R': + case 'r': + XBell(XtDisplay(w), 0); + /*FALLTROUGH*/ + default: + break; + } +} + +/* Reconnect() - action + * This reconnects to the input method. The user will typically call + * this action if/when connection has been severed, or when the app + * was started up before an IM was started up + */ +/*ARGSUSED*/ +static void +Reconnect(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + _XawImReconnect(w); +} + +#define CAPITALIZE 1 +#define DOWNCASE 2 +#define UPCASE 3 + +#ifdef NO_LIBC_I18N +static int +ToLower(int ch) +{ + char buf[2]; + + *buf = ch; + XmuNCopyISOLatin1Lowered(buf, buf, sizeof(buf)); + + return (*buf); +} + +static int +ToUpper(int ch) +{ + char buf[2]; + + *buf = ch; + XmuNCopyISOLatin1Uppered(buf, buf, sizeof(buf)); + + return (*buf); +} + +static int +IsAlnum(int ch) +{ + return ((ch >= '0' && ch <= '9') || ToUpper(ch) != ch || ToLower(ch) != ch); +} + +static int +IsLower(int ch) +{ + char upbuf[2]; + char lobuf[2]; + + *upbuf = *lobuf = ch; + XmuNCopyISOLatin1Lowered(lobuf, lobuf, sizeof(lobuf)); + XmuNCopyISOLatin1Uppered(upbuf, upbuf, sizeof(upbuf)); + + return (*lobuf != *upbuf && ch == *lobuf); +} + +static int +IsUpper(int ch) +{ + char upbuf[2]; + char lobuf[2]; + + *upbuf = *lobuf = ch; + XmuNCopyISOLatin1Lowered(lobuf, lobuf, sizeof(lobuf)); + XmuNCopyISOLatin1Uppered(upbuf, upbuf, sizeof(upbuf)); + + return (*lobuf != *upbuf && ch == *upbuf); +} +#else +#define ToLower tolower +#define ToUpper toupper +#define IsAlnum isalnum +#define IsLower islower +#define IsUpper isupper +#endif + +static void +CaseProc(Widget w, XEvent *event, int cmd) +{ + TextWidget ctx = (TextWidget)w; + short mul = MULT(ctx); + XawTextPosition left, right; + XawTextBlock block; + Bool changed = False; + unsigned char ch, mb[sizeof(wchar_t)]; + int i, count; + + if (mul > 0) + right = SrcScan(ctx->text.source, left = ctx->text.insertPos, + XawstAlphaNumeric, XawsdRight, mul, False); + else + left = SrcScan(ctx->text.source, right = ctx->text.insertPos, + XawstAlphaNumeric, XawsdLeft, 1 + -mul, False); + block.firstPos = 0; + block.format = _XawTextFormat(ctx); + block.length = right - left; + block.ptr = _XawTextGetText(ctx, left, right); + + count = 0; + if (block.format == XawFmt8Bit) + for (i = 0; i < block.length; i++) { + if (!IsAlnum(*mb = (unsigned char)block.ptr[i])) + count = 0; + else if (++count == 1 || cmd != CAPITALIZE) { + ch = cmd == DOWNCASE ? ToLower(*mb) : ToUpper(*mb); + if (ch != *mb) { + changed = True; + block.ptr[i] = ch; + } + } + else if (cmd == CAPITALIZE) { + if ((ch = ToLower(*mb)) != *mb) { + changed = True; + block.ptr[i] = ch; + } + } + } + else + for (i = 0; i < block.length; i++) { + wctomb((char*)mb, ((wchar_t*)block.ptr)[i]); + if (!IsAlnum(*mb)) + count = 0; + else if (++count == 1 || cmd != CAPITALIZE) { + ch = cmd == DOWNCASE ? ToLower(*mb) : ToUpper(*mb); + if (ch != *mb) { + changed = True; + ((wchar_t*)block.ptr)[i] = _Xaw_atowc(ch); + } + } + else if (cmd == CAPITALIZE) { + if ((ch = ToLower(*mb)) != *mb) { + changed = True; + ((wchar_t*)block.ptr)[i] = _Xaw_atowc(ch); + } + } + } + + StartAction(ctx, event); + if (changed && _XawTextReplace(ctx, left, right, &block) != XawEditDone) + XBell(XtDisplay(ctx), 0); + ctx->text.insertPos = right; + EndAction(ctx); + + XtFree(block.ptr); +} + +/*ARGSUSED*/ +static void +CapitalizeWord(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + CaseProc(w, event, CAPITALIZE); +} + +/*ARGSUSED*/ +static void +DowncaseWord(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + CaseProc(w, event, DOWNCASE); +} + +/*ARGSUSED*/ +static void +UpcaseWord(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + CaseProc(w, event, UPCASE); +} +#undef CAPITALIZE +#undef DOWNCASE +#undef UPCASE + +XtActionsRec _XawTextActionsTable[] = { + /* motion */ + {"forward-character", MoveForwardChar}, + {"backward-character", MoveBackwardChar}, + {"forward-word", MoveForwardWord}, + {"backward-word", MoveBackwardWord}, + {"forward-paragraph", MoveForwardParagraph}, + {"backward-paragraph", MoveBackwardParagraph}, + {"beginning-of-line", MoveToLineStart}, + {"end-of-line", MoveToLineEnd}, + {"next-line", MoveNextLine}, + {"previous-line", MovePreviousLine}, + {"next-page", MoveNextPage}, + {"previous-page", MovePreviousPage}, + {"beginning-of-file", MoveBeginningOfFile}, + {"end-of-file", MoveEndOfFile}, + {"scroll-one-line-up", ScrollOneLineUp}, + {"scroll-one-line-down", ScrollOneLineDown}, + + /* delete */ + {"delete-next-character", DeleteForwardChar}, + {"delete-previous-character", DeleteBackwardChar}, + {"delete-next-word", DeleteForwardWord}, + {"delete-previous-word", DeleteBackwardWord}, + {"delete-selection", DeleteCurrentSelection}, + {"delete", Delete}, + + /* kill */ + {"kill-word", KillForwardWord}, + {"backward-kill-word", KillBackwardWord}, + {"kill-selection", KillCurrentSelection}, + {"kill-to-end-of-line", KillToEndOfLine}, + {"kill-to-end-of-paragraph", KillToEndOfParagraph}, + + /* new line */ + {"newline-and-indent", InsertNewLineAndIndent}, + {"newline-and-backup", InsertNewLineAndBackup}, + {"newline", InsertNewLine}, + + /* selection */ + {"select-word", SelectWord}, + {"select-all", SelectAll}, + {"select-start", SelectStart}, + {"select-adjust", SelectAdjust}, + {"select-end", SelectEnd}, + {"select-save", SelectSave}, + {"extend-start", ExtendStart}, + {"extend-adjust", ExtendAdjust}, + {"extend-end", ExtendEnd}, + {"insert-selection", InsertSelection}, + + /* miscellaneous */ + {"redraw-display", RedrawDisplay}, + {"insert-file", _XawTextInsertFile}, + {"search", _XawTextSearch}, + {"insert-char", InsertChar}, + {"insert-string", InsertString}, + {"focus-in", TextFocusIn}, + {"focus-out", TextFocusOut}, + {"enter-window", TextEnterWindow}, + {"leave-window", TextLeaveWindow}, + {"display-caret", DisplayCaret}, + {"multiply", Multiply}, + {"form-paragraph", FormParagraph}, + {"transpose-characters", TransposeCharacters}, + {"set-keyboard-focus", SetKeyboardFocus}, +#ifndef OLDXAW + {"numeric", Numeric}, + {"undo", Undo}, + {"keyboard-reset", KeyboardReset}, + {"kill-ring-yank", KillRingYank}, + {"toggle-overwrite", ToggleOverwrite}, + {"indent", Indent}, +#endif + {"no-op", NoOp}, + + /* case transformations */ + {"capitalize-word", CapitalizeWord}, + {"downcase-word", DowncaseWord}, + {"upcase-word", UpcaseWord}, + + /* action to bind translations for text dialogs */ + {"InsertFileAction", _XawTextInsertFileAction}, + {"DoSearchAction", _XawTextDoSearchAction}, + {"DoReplaceAction", _XawTextDoReplaceAction}, + {"SetField", _XawTextSetField}, + {"PopdownSearchAction", _XawTextPopdownSearchAction}, + + /* reconnect to Input Method */ + {"reconnect-im", Reconnect} /* Li Yuhong, Omron KK, 1991 */ +}; + +Cardinal _XawTextActionsTableCount = XtNumber(_XawTextActionsTable); diff --git a/src/TextPop.c b/src/TextPop.c new file mode 100644 index 0000000..953fa9a --- /dev/null +++ b/src/TextPop.c @@ -0,0 +1,1549 @@ +/* + +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* + * This file is broken up into three sections one dealing with + * each of the three popups created here: + * + * FileInsert, Search, and Replace. + * + * There is also a section at the end for utility functions + * used by all more than one of these dialogs. + * + * The following functions are the only non-static ones defined + * in this module. They are located at the begining of the + * section that contains this dialog box that uses them. + * + * void _XawTextInsertFileAction(w, event, params, num_params); + * void _XawTextDoSearchAction(w, event, params, num_params); + * void _XawTextDoReplaceAction(w, event, params, num_params); + * void _XawTextInsertFile(w, event, params, num_params); + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "XawI18n.h" + +static char* INSERT_FILE = "Enter Filename:"; +static char* SEARCH_LABEL_1 = "Use to change fields."; +static char* SEARCH_LABEL_2 = "Use ^q for ."; +static char* DISMISS_NAME = "cancel"; +#define DISMISS_NAME_LEN 6 +static char* FORM_NAME = "form"; +static char* LABEL_NAME = "label"; +static char* TEXT_NAME = "text"; + +#define R_OFFSET 1 + +typedef void (*AddFunc)(Widget, char*, Widget); + +/* + * Prototypes + */ +static void _SetField(Widget, Widget); +static void AddSearchChildren(Widget, char*, Widget); +static void AddInsertFileChildren(Widget, char*, Widget); +static void CenterWidgetOnPoint(Widget, XEvent*); +static Widget CreateDialog(Widget, String, String, AddFunc); +static void DoInsert(Widget, XtPointer, XtPointer); +static void DoReplaceAll(Widget, XtPointer, XtPointer); +static void DoReplaceOne(Widget, XtPointer, XtPointer); +static Bool DoSearch(struct SearchAndReplace*); +static Widget GetShell(Widget); +static String GetString(Widget); +static String GetStringRaw(Widget); +static void InitializeSearchWidget(struct SearchAndReplace*, + XawTextScanDirection, Bool); +static Bool InParams(String, String*, unsigned int); +static Bool InsertFileNamed(Widget, char*); +static void PopdownFileInsert(Widget, XtPointer, XtPointer); +static void PopdownSearch(Widget, XtPointer, XtPointer); +static Bool Replace(struct SearchAndReplace*, Bool, Bool); +static void SearchButton(Widget, XtPointer, XtPointer); +static void SetResource(Widget, char*, XtArgVal); +static Bool SetResourceByName(Widget, char*, char*, XtArgVal); +static void SetSearchLabels(struct SearchAndReplace*, String, String, Bool); +static void SetWMProtocolTranslations(Widget); + +/* + * Actions + */ +static void WMProtocols(Widget, XEvent*, String*, Cardinal*); + +/* + * External Actions + */ +void _XawTextDoReplaceAction(Widget, XEvent*, String*, Cardinal*); +void _XawTextDoSearchAction(Widget, XEvent*, String*, Cardinal*); +void _XawTextInsertFile(Widget, XEvent*, String*, Cardinal*); +void _XawTextInsertFileAction(Widget, XEvent*, String*, Cardinal*); +void _XawTextPopdownSearchAction(Widget, XEvent*, String*, Cardinal*); +void _XawTextSearch(Widget, XEvent*, String*, Cardinal*); +void _XawTextSetField(Widget, XEvent*, String*, Cardinal*); + +/* + * From Text.c + */ +char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition); +void _XawTextShowPosition(TextWidget); + +/* + * Initialization + */ +static char radio_trans_string[] = +",:" "set() notify()\n" +; + +static char search_text_trans[] = +"~sReturn:" "DoSearchAction(Popdown)\n" +"sReturn:" "DoSearchAction() SetField(Replace)\n" +"cc:" "PopdownSearchAction()\n" +":" "select-start() SetField(Search)\n" +"Tab:" "DoSearchAction() SetField(Replace)\n" +; + +static char rep_text_trans[] = +"~sReturn:" "DoReplaceAction(Popdown)\n" +"sReturn:" "SetField(Search)\n" +"cc:" "PopdownSearchAction()\n" +":" "select-start() DoSearchAction() SetField(Replace)\n" +"Tab:" "SetField(Search)\n" +; + +/* + * Implementation + */ +/* + * This section of the file contains all the functions that + * the file insert dialog box uses + */ + +/* + * Function: + * _XawTextInsertFileAction + * + * Description: + * Action routine that can be bound to dialog box's Text Widget + * that will insert a file into the main Text Widget. + */ +/*ARGSUSED*/ +void +_XawTextInsertFileAction(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + DoInsert(w, (XtPointer)XtParent(XtParent(XtParent(w))), NULL); +} + +/* + * Function: + * _XawTextInsertFile + * + * Parameters: + * w - text widget + * event - X Event (used to get x and y location) + * params - parameter list + * num_params - "" + * + * Description: + * Action routine that can be bound to the text widget + * it will popup the insert file dialog box. + * + * Note: + * The parameter list may contain one entry + * + * Entry: + * This entry is optional and contains the value of the default + * file to insert + */ +void +_XawTextInsertFile(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + char *ptr; + XawTextEditType edit_mode; + Arg args[1]; + + XtSetArg(args[0], XtNeditType, &edit_mode); + XtGetValues(ctx->text.source, args, 1); + + if (edit_mode != XawtextEdit) { + XBell(XtDisplay(w), 0); + return; + } + + if (*num_params == 0) + ptr = ""; + else + ptr = params[0]; + + if (!ctx->text.file_insert) { + ctx->text.file_insert = CreateDialog(w, ptr, "insertFile", + AddInsertFileChildren); + XtRealizeWidget(ctx->text.file_insert); + SetWMProtocolTranslations(ctx->text.file_insert); + } + + CenterWidgetOnPoint(ctx->text.file_insert, event); + XtPopup(ctx->text.file_insert, XtGrabNone); +} + +/* + * Function: + * PopdownFileInsert + * + * Parameters: + * w - widget that caused this action + * closure - pointer to the main text widget that popped up this dialog + * call_data - (not used) + * + * Description: + * Pops down the file insert button + */ +/*ARGSUSED*/ +static void +PopdownFileInsert(Widget w, XtPointer closure, XtPointer call_data) +{ + TextWidget ctx = (TextWidget)closure; + + XtPopdown(ctx->text.file_insert); + (void)SetResourceByName(ctx->text.file_insert, LABEL_NAME, + XtNlabel, (XtArgVal)INSERT_FILE); +} + +/* + * Function: + * DoInsert + * + * Parameters: + * w - widget that activated this callback + * closure - pointer to the text widget to insert the file into + * + * Description: + * Actually insert the file named in the text widget of the file dialog + */ +/*ARGSUSED*/ +static void +DoInsert(Widget w, XtPointer closure, XtPointer call_data) +{ + TextWidget ctx = (TextWidget)closure; + char buf[BUFSIZ], msg[BUFSIZ]; + Widget temp_widget; + + snprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, TEXT_NAME); + if ((temp_widget = XtNameToWidget(ctx->text.file_insert, buf)) == NULL) { + (void)strcpy(msg, + "Error: Could not get text widget from file insert popup"); + } + else if (InsertFileNamed((Widget)ctx, GetString(temp_widget))) { + PopdownFileInsert(w, closure, call_data); + return; + } + else + snprintf(msg, sizeof(msg), "Error: %s", strerror(errno)); + + (void)SetResourceByName(ctx->text.file_insert, + LABEL_NAME, XtNlabel, (XtArgVal)msg); + XBell(XtDisplay(w), 0); +} + +/* + * Function: + * InsertFileNamed + * + * Parameters: + * tw - text widget to insert this file into + * str - name of the file to insert + * + * Description: + * Inserts a file into the text widget. + * + * Returns: + * True if the insert was sucessful, False otherwise. + */ +static Bool +InsertFileNamed(Widget tw, char *str) +{ + FILE *file; + XawTextBlock text; + XawTextPosition pos; + + if (str == NULL || strlen(str) == 0 || (file = fopen(str, "r")) == NULL) + return (False); + + pos = XawTextGetInsertionPoint(tw); + + fseek(file, 0L, 2); + + text.firstPos = 0; + text.length = ftell(file); + text.ptr = XtMalloc(text.length + 1); + text.format = XawFmt8Bit; + + fseek(file, 0L, 0); + if (fread(text.ptr, 1, text.length, file) != text.length) + XtErrorMsg("readError", "insertFileNamed", "XawError", + "fread returned error", NULL, NULL); + + if (XawTextReplace(tw, pos, pos, &text) != XawEditDone) { + XtFree(text.ptr); + fclose(file); + return (False); + } + pos += text.length; + XtFree(text.ptr); + fclose(file); + XawTextSetInsertionPoint(tw, pos); + _XawTextShowPosition((TextWidget)tw); + + return (True); +} + +/* + * Function: + * AddInsertFileChildren + * + * Parameters: + * form - form widget for the insert dialog widget + * ptr - pointer to the initial string for the Text Widget + * tw - main text widget + * + * Description: + * Adds all children to the InsertFile dialog widget. + */ +static void +AddInsertFileChildren(Widget form, char *ptr, Widget tw) +{ + Arg args[10]; + Cardinal num_args; + Widget label, text, cancel, insert; + XtTranslations trans; + + num_args = 0; + XtSetArg(args[num_args], XtNlabel, INSERT_FILE); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNresizable, True); num_args++; + XtSetArg(args[num_args], XtNborderWidth, 0); num_args++; + label = XtCreateManagedWidget(LABEL_NAME, labelWidgetClass, form, + args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNfromVert, label); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainRight); num_args++; + XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++; + XtSetArg(args[num_args], XtNresizable, True); num_args++; + XtSetArg(args[num_args], XtNstring, ptr); num_args++; + text = XtCreateManagedWidget(TEXT_NAME, asciiTextWidgetClass, form, + args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNlabel, "Insert File"); num_args++; + XtSetArg(args[num_args], XtNfromVert, text); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + insert = XtCreateManagedWidget("insert", commandWidgetClass, form, + args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++; + XtSetArg(args[num_args], XtNfromVert, text); num_args++; + XtSetArg(args[num_args], XtNfromHoriz, insert); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form, + args, num_args); + + XtAddCallback(cancel, XtNcallback, PopdownFileInsert, (XtPointer)tw); + XtAddCallback(insert, XtNcallback, DoInsert, (XtPointer)tw); + + XtSetKeyboardFocus(form, text); + + /* + * Bind to insert file + */ + trans = XtParseTranslationTable("Return:InsertFileAction()"); + XtOverrideTranslations(text, trans); +} + +/* + * This section of the file contains all the functions that + * the search dialog box uses + */ +/* + * Function: + * _XawTextDoSearchAction + * + * Description: + * Action routine that can be bound to dialog box's Text Widget that + * will search for a string in the main Text Widget. + * + * Note: + * If the search was sucessful and the argument popdown is passed to + * this action routine then the widget will automatically popdown the + * search widget + */ +/*ARGSUSED*/ +void +_XawTextDoSearchAction(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w))); + Bool popdown = False; + + if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P')) + popdown = True; + + if (DoSearch(tw->text.search) && popdown) + PopdownSearch(w, (XtPointer)tw->text.search, NULL); +} + +/* + * Function: + * _XawTextPopdownSearchAction + * + * Description: + * Action routine that can be bound to dialog box's Text Widget that + * will popdown the search widget. + */ +/*ARGSUSED*/ +void +_XawTextPopdownSearchAction(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w))); + + PopdownSearch(w, (XtPointer)tw->text.search, NULL); +} + +/* + * Function: + * PopdownSearch + * + * Parameters: + * w - (not used) + * closure - pointer to the search structure + * call_data - (not used) + * + * Description: + * Pops down the search widget and resets it + */ +/*ARGSUSED*/ +static void +PopdownSearch(Widget w, XtPointer closure, XtPointer call_data) +{ + struct SearchAndReplace *search = (struct SearchAndReplace *)closure; + + XtPopdown(search->search_popup); + SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False); +} + +/* + * Function: + * SearchButton + * + * Arguments: + * w - (not used) + * closure - pointer to the search info + * call_data - (not used) + * + * Description: + * Performs a search when the button is clicked. + */ +/*ARGSUSED*/ +static void +SearchButton(Widget w, XtPointer closure, XtPointer call_data) +{ + (void)DoSearch((struct SearchAndReplace *)closure); +} + +/* + * Function: + * _XawTextSearch + * + * Parameters: + * w - text widget + * event - X Event (used to get x and y location) + * params - parameter list + * num_params - "" + * + * Description: + * Action routine that can be bound to the text widget + * it will popup the search dialog box. + * + * Note: + * The parameter list contains one or two entries that may be + * the following. + * + * First Entry: + * The first entry is the direction to search by default. + * This arguement must be specified and may have a value of + * "left" or "right". + * + * Second Entry: + * This entry is optional and contains the value of the default + * string to search for. + */ + +#define SEARCH_HEADER "Text Widget - Search():" +void +_XawTextSearch(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)w; + XawTextScanDirection dir; + char *ptr, buf[BUFSIZ]; + XawTextEditType edit_mode; + Arg args[1]; + wchar_t wcs[1]; + + if (*num_params < 1 || *num_params > 2) { + snprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER, + "This action must have only", + "one or two parameters"); + XtAppWarning(XtWidgetToApplicationContext(w), buf); + return; + } + + if (*num_params == 2) + ptr = params[1]; + else if (XawTextFormat(ctx, XawFmtWide)) { + /* This just does the equivalent of + ptr = ""L, a waste because params[1] isnt W aligned */ + ptr = (char *)wcs; + wcs[0] = 0; + } + else + ptr = ""; + + switch(params[0][0]) { + case 'b': /* Left */ + case 'B': + dir = XawsdLeft; + break; + case 'f': /* Right */ + case 'F': + dir = XawsdRight; + break; + default: + snprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER, + "The first parameter must be", + "Either 'backward' or 'forward'"); + XtAppWarning(XtWidgetToApplicationContext(w), buf); + return; + } + + if (ctx->text.search== NULL) { + ctx->text.search = XtNew(struct SearchAndReplace); + ctx->text.search->search_popup = CreateDialog(w, ptr, "search", + AddSearchChildren); + XtRealizeWidget(ctx->text.search->search_popup); + SetWMProtocolTranslations(ctx->text.search->search_popup); + } + else if (*num_params > 1) + XtVaSetValues(ctx->text.search->search_text, XtNstring, ptr, NULL); + + XtSetArg(args[0], XtNeditType,&edit_mode); + XtGetValues(ctx->text.source, args, 1); + + InitializeSearchWidget(ctx->text.search, dir, (edit_mode == XawtextEdit)); + + CenterWidgetOnPoint(ctx->text.search->search_popup, event); + XtPopup(ctx->text.search->search_popup, XtGrabNone); +} + +/* + * Function: + * InitializeSearchWidget + * + * Parameters: + * search - search widget structure + * dir - direction to search + * replace_active - state of the sensitivity for the replace button + * + * Description: + * This function initializes the search widget and + * is called each time the search widget is poped up. + */ +static void +InitializeSearchWidget(struct SearchAndReplace *search, + XawTextScanDirection dir, Bool replace_active) +{ + SetResource(search->rep_one, XtNsensitive, (XtArgVal)replace_active); + SetResource(search->rep_all, XtNsensitive, (XtArgVal)replace_active); + SetResource(search->rep_label, XtNsensitive, (XtArgVal)replace_active); + SetResource(search->rep_text, XtNsensitive, (XtArgVal)replace_active); + + switch (dir) { + case XawsdLeft: + SetResource(search->left_toggle, XtNstate, (XtArgVal)True); + break; + case XawsdRight: + SetResource(search->right_toggle, XtNstate, (XtArgVal)True); + break; + } +} + +/* + * Function: + * AddSearchChildren + * + * Parameters: + * form - form widget for the search widget + * ptr - pointer to the initial string for the Text Widget + * tw - main text widget + * + * Description: + * Adds all children to the Search Dialog Widget. + */ +static void +AddSearchChildren(Widget form, char *ptr, Widget tw) +{ + Arg args[10]; + Cardinal num_args; + Widget cancel, search_button, s_label, s_text, r_text; + XtTranslations trans; + struct SearchAndReplace *search = ((TextWidget)tw)->text.search; + + num_args = 0; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNresizable, True); num_args++; + XtSetArg(args[num_args], XtNborderWidth, 0); num_args++; + search->label1 = XtCreateManagedWidget("label1", labelWidgetClass, form, + args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNfromVert, search->label1); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNresizable, True); num_args++; + XtSetArg(args[num_args], XtNborderWidth, 0); num_args++; + search->label2 = XtCreateManagedWidget("label2", labelWidgetClass, form, + args, num_args); + + /* + * We need to add R_OFFSET to the radio_data, because the value zero (0) + * has special meaning + */ + num_args = 0; + XtSetArg(args[num_args], XtNlabel, "Backward"); num_args++; + XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdLeft + R_OFFSET); + num_args++; + search->left_toggle = XtCreateManagedWidget("backwards", toggleWidgetClass, + form, args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNlabel, "Forward"); num_args++; + XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++; + XtSetArg(args[num_args], XtNfromHoriz, search->left_toggle); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNradioGroup, search->left_toggle); num_args++; + XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdRight + R_OFFSET); + num_args++; + search->right_toggle = XtCreateManagedWidget("forwards", toggleWidgetClass, + form, args, num_args); + + { + XtTranslations radio_translations; + + radio_translations = XtParseTranslationTable(radio_trans_string); + XtOverrideTranslations(search->left_toggle, radio_translations); + XtOverrideTranslations(search->right_toggle, radio_translations); + } + +#ifndef OLDXAW + if (XawTextFormat((TextWidget)tw, XawFmt8Bit)) { + num_args = 0; + XtSetArg(args[num_args], XtNlabel, "Case Sensitive"); num_args++; + XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++; + XtSetArg(args[num_args], XtNfromHoriz, search->right_toggle); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNstate, True); num_args++; + search->case_sensitive = XtCreateManagedWidget("case", toggleWidgetClass, + form, args, num_args); + } + else + search->case_sensitive = NULL; +#endif + + num_args = 0; + XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++; + XtSetArg(args[num_args], XtNlabel, "Search for: "); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++; + s_label = XtCreateManagedWidget("searchLabel", labelWidgetClass, form, + args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++; + XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainRight); num_args++; + XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++; + XtSetArg(args[num_args], XtNresizable, True); num_args++; + XtSetArg(args[num_args], XtNstring, ptr); num_args++; + s_text = XtCreateManagedWidget("searchText", asciiTextWidgetClass, form, + args, num_args); + search->search_text = s_text; + + num_args = 0; + XtSetArg(args[num_args], XtNfromVert, s_text); num_args++; + XtSetArg(args[num_args], XtNlabel, "Replace with:"); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNborderWidth, 0); num_args++; + search->rep_label = XtCreateManagedWidget("replaceLabel", labelWidgetClass, + form, args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++; + XtSetArg(args[num_args], XtNfromVert, s_text); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainRight); num_args++; + XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++; + XtSetArg(args[num_args], XtNresizable, True); num_args++; + XtSetArg(args[num_args], XtNstring, ""); num_args++; + r_text = XtCreateManagedWidget("replaceText", asciiTextWidgetClass, + form, args, num_args); + search->rep_text = r_text; + + num_args = 0; + XtSetArg(args[num_args], XtNlabel, "Search"); num_args++; + XtSetArg(args[num_args], XtNfromVert, r_text); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + search_button = XtCreateManagedWidget("search", commandWidgetClass, form, + args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNlabel, "Replace"); num_args++; + XtSetArg(args[num_args], XtNfromVert, r_text); num_args++; + XtSetArg(args[num_args], XtNfromHoriz, search_button); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + search->rep_one = XtCreateManagedWidget("replaceOne", commandWidgetClass, + form, args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNlabel, "Replace All"); num_args++; + XtSetArg(args[num_args], XtNfromVert, r_text); num_args++; + XtSetArg(args[num_args], XtNfromHoriz, search->rep_one); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + search->rep_all = XtCreateManagedWidget("replaceAll", commandWidgetClass, + form, args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++; + XtSetArg(args[num_args], XtNfromVert, r_text); num_args++; + XtSetArg(args[num_args], XtNfromHoriz, search->rep_all); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++; + cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form, + args, num_args); + + XtAddCallback(search_button, XtNcallback, SearchButton, (XtPointer)search); + XtAddCallback(search->rep_one, XtNcallback, DoReplaceOne, (XtPointer)search); + XtAddCallback(search->rep_all, XtNcallback, DoReplaceAll, (XtPointer)search); + XtAddCallback(cancel, XtNcallback, PopdownSearch, (XtPointer)search); + + /* + * Initialize the text entry fields + */ + { + Pixel color; + + num_args = 0; + XtSetArg(args[num_args], XtNbackground, &color); num_args++; + XtGetValues(search->rep_text, args, num_args); + num_args = 0; + XtSetArg(args[num_args], XtNborderColor, color); num_args++; + XtSetValues(search->rep_text, args, num_args); + XtSetKeyboardFocus(form, search->search_text); + } + + SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False); + + /* + * Bind Extra translations + */ + trans = XtParseTranslationTable(search_text_trans); + XtOverrideTranslations(search->search_text, trans); + + trans = XtParseTranslationTable(rep_text_trans); + XtOverrideTranslations(search->rep_text, trans); +} + +/* + * Function: + * DoSearch + * + * Parameters: + * search - search structure + * + * Description: + * Performs a search + * + * Returns: + * True if sucessful + */ +/*ARGSUSED*/ +static Bool +DoSearch(struct SearchAndReplace *search) +{ + char msg[37]; + Widget tw = XtParent(search->search_popup); + XawTextPosition pos; + XawTextScanDirection dir; + XawTextBlock text; + TextWidget ctx = (TextWidget)tw; + + text.firstPos = 0; + text.ptr = GetStringRaw(search->search_text); + if ((text.format = _XawTextFormat(ctx)) == XawFmtWide) + text.length = wcslen((wchar_t*)text.ptr); + else { + text.length = strlen(text.ptr); + +#ifndef OLDXAW + if (search->case_sensitive) { + /* text.firstPos isn't useful here, so I'll use it as an + * options flag. + */ + Arg args[1]; + Boolean case_sensitive; + + XtSetArg(args[0], XtNstate, &case_sensitive); + XtGetValues(search->case_sensitive, args, 1); + text.firstPos = !case_sensitive; + } +#endif /* OLDXAW */ + } + + dir = (XawTextScanDirection)(unsigned long) + ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET); + + pos = XawTextSearch(tw, dir, &text); + + /* The Raw string in find.ptr may be WC I can't use here, so I re - call + GetString to get a tame version */ + + if (pos == XawTextSearchError) { + char *ptr; + int len; + + ptr = GetString(search->search_text); + len = strlen(ptr); + snprintf(msg, sizeof(msg), "%s", ptr); + + ptr = strchr(msg, '\n'); + if (ptr != NULL || sizeof(msg) - 1 < len) { + if (ptr != NULL) + len = ptr - msg + 4; + else + len = strlen(msg); + + if (len < 4) + strcpy(msg, "..."); + else + strcpy(msg + len - 4, "..."); + } + XawTextUnsetSelection(tw); + SetSearchLabels(search, "Could not find string", msg, True); + + return (False); + } + XawTextDisableRedisplay(tw); + XawTextSetSelection(tw, pos, pos + text.length); + search->selection_changed = False; /* selection is good */ + + if (dir == XawsdRight) + XawTextSetInsertionPoint(tw, pos + text.length); + else + XawTextSetInsertionPoint(tw, pos); + _XawTextShowPosition(ctx); + XawTextEnableRedisplay(tw); + + return (True); +} + +/* + * This section of the file contains all the functions that + * the replace dialog box uses + */ +/* + * Function: + * _XawTextDoReplaceAction + * + * Description: + * Action routine that can be bound to dialog box's + * Text Widget that will replace a string in the main Text Widget. + */ +/*ARGSUSED*/ +void +_XawTextDoReplaceAction(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + TextWidget ctx = (TextWidget)XtParent(XtParent(XtParent(w))); + Bool popdown = False; + + if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P')) + popdown = True; + + if (Replace( ctx->text.search, True, popdown) && popdown) + PopdownSearch(w, (XtPointer)ctx->text.search, NULL); +} + +/* + * Function: + * DoReplaceOne + * + * Arguments: + * w - *** Not Used *** + * closure - a pointer to the search structure + * call_data - *** Not Used *** + * + * Description: + * Replaces the first instance of the string in the search + * dialog's text widget with the one in the replace dialog's text widget. + */ +/*ARGSUSED*/ +static void +DoReplaceOne(Widget w, XtPointer closure, XtPointer call_data) +{ + Replace((struct SearchAndReplace *)closure, True, False); +} + +/* + * Function: + * DoReplaceAll + * + * Parameters: + * w - (not used) + * closure - pointer to the search structure + * call_data - (not used) + * + * Description: + * Replaces every instance of the string in the search dialog's + * text widget with the one in the replace dialog's text widget. + */ +/*ARGSUSED*/ +static void +DoReplaceAll(Widget w, XtPointer closure, XtPointer call_data) +{ + Replace((struct SearchAndReplace *)closure, False, False); +} + +/* + * Function: + * Replace + * + * Parameters: + * tw - Text Widget to replce the string in + * once_only - if True then only replace the first one found, + * else replace all of them + * show_current - if true then leave the selection on the + * string that was just replaced, otherwise + * move it onto the next one + * + * Description: + * This is the function that does the real work of + * replacing strings in the main text widget. + */ +static Bool +Replace(struct SearchAndReplace *search, Bool once_only, Bool show_current) +{ + XawTextPosition pos, new_pos, end_pos, ipos; + XawTextScanDirection dir; + XawTextBlock find, replace; + Widget tw = XtParent(search->search_popup); + int count = 0; + TextWidget ctx = (TextWidget)tw; + Bool redisplay; + + find.ptr = GetStringRaw(search->search_text); + if ((find.format = _XawTextFormat(ctx)) == XawFmtWide) + find.length = (XawTextPosition)wcslen((wchar_t*)find.ptr); + else + find.length = (XawTextPosition)strlen(find.ptr); + find.firstPos = 0; + + replace.ptr = GetStringRaw(search->rep_text); + replace.firstPos = 0; + if ((replace.format = _XawTextFormat(ctx)) == XawFmtWide) + replace.length = wcslen((wchar_t*)replace.ptr); + else + replace.length = strlen(replace.ptr); + + dir = (XawTextScanDirection)(unsigned long) + ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET); + + redisplay = !once_only || (once_only && !show_current); + ipos = XawTextGetInsertionPoint(tw); + if (redisplay) + XawTextDisableRedisplay(tw); + /*CONSTCOND*/ + while (True) { + if (count != 0) { + new_pos = XawTextSearch(tw, dir, &find); + + if (new_pos == XawTextSearchError) { + if (count == 0) { + char msg[37]; + char *ptr; + int len; + + ptr = GetString(search->search_text); + len = strlen(ptr); + snprintf(msg, sizeof(msg), "%s", ptr); + ptr = strchr(msg, '\n'); + if (ptr != NULL || sizeof(msg) - 1 < len) { + if (ptr != NULL) + len = ptr - msg + 4; + else + len = strlen(msg); + + if (len < 4) + strcpy(msg, "..."); + else + strcpy(msg + len - 4, "..."); + } + SetSearchLabels(search, "Could not find string", msg, True); + + if (redisplay) { + XawTextSetInsertionPoint(tw, ipos); + _XawTextShowPosition(ctx); + XawTextEnableRedisplay(tw); + } + + return (False); + } + else + break; + } + pos = new_pos; + end_pos = pos + find.length; + } + else { + XawTextGetSelectionPos(tw, &pos, &end_pos); + + if (search->selection_changed) { + SetSearchLabels(search, "Selection modified, aborting.", + "", True); + if (redisplay) { + XawTextSetInsertionPoint(tw, ipos); + XawTextEnableRedisplay(tw); + } + + return (False); + } + if (pos == end_pos) { + if (redisplay) { + XawTextSetInsertionPoint(tw, ipos); + XawTextEnableRedisplay(tw); + } + + return (False); + } + } + + if (XawTextReplace(tw, pos, end_pos, &replace) != XawEditDone) { + SetSearchLabels(search, "Error while replacing.", "", True); + if (redisplay) { + XawTextSetInsertionPoint(tw, ipos); + XawTextEnableRedisplay(tw); + } + + return (False); + } + + if (dir == XawsdRight) + ipos = pos + replace.length; + else + ipos = pos; + + if (once_only) { + if (show_current) + break; + else { + DoSearch(search); + XawTextEnableRedisplay(tw); + + return (True); + } + } + else + ctx->text.insertPos = ipos; + count++; + } + + if (replace.length == 0) + XawTextUnsetSelection(tw); + else + XawTextSetSelection(tw, pos, pos + replace.length); + + XawTextSetInsertionPoint(tw, ipos); + _XawTextShowPosition(ctx); + XawTextEnableRedisplay(tw); + + return (True); +} + +/* + * Function: + * SetSearchLabels + * + * Parameters: + * search - search structure + * msg1 - message to put in each search label + * msg2 - "" + * bell - if True then ring bell + * + * Description: + * Sets both the search labels, and also rings the bell. + */ +static void +SetSearchLabels(struct SearchAndReplace *search, String msg1, String msg2, + Bool bell) +{ + (void)SetResource(search->label1, XtNlabel, (XtArgVal)msg1); + (void)SetResource(search->label2, XtNlabel, (XtArgVal)msg2); + if (bell) + XBell(XtDisplay(search->search_popup), 0); +} + +/* + * This section of the file contains utility routines used by + * other functions in this file + */ +/* + * Function: + * _XawTextSetField + * + * Description: + * Action routine that can be bound to dialog box's + * Text Widget that will send input to the field specified. + */ +/*ARGSUSED*/ +void +_XawTextSetField(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + struct SearchAndReplace *search; + Widget cnew, old; + + search = ((TextWidget)XtParent(XtParent(XtParent(w))))->text.search; + + if (*num_params != 1) { + SetSearchLabels(search, "Error: SetField Action must have", + "exactly one argument", True); + return; + } + switch (params[0][0]) { + case 's': + case 'S': + cnew = search->search_text; + old = search->rep_text; + break; + case 'r': + case 'R': + old = search->search_text; + cnew = search->rep_text; + break; + default: + SetSearchLabels(search, + "Error: SetField Action's first Argument must", + "be either 'Search' or 'Replace'", True); + return; + } + _SetField(cnew, old); +} + +/* + * Function: + * _SetField + * + * Parameters: + * cnew - new and old text fields + * old - "" + * + * Description: + * Sets the current text field. + */ +static void +_SetField(Widget cnew, Widget old) +{ + Arg args[2]; + Pixel new_border, old_border, old_bg; + + if (!XtIsSensitive(cnew)) { + XBell(XtDisplay(old), 0); /* Don't set field to an inactive Widget */ + return; + } + + XtSetKeyboardFocus(XtParent(cnew), cnew); + + XtSetArg(args[0], XtNborderColor, &old_border); + XtSetArg(args[1], XtNbackground, &old_bg); + XtGetValues(cnew, args, 2); + + XtSetArg(args[0], XtNborderColor, &new_border); + XtGetValues(old, args, 1); + + if (old_border != old_bg) /* Colors are already correct, return */ + return; + + SetResource(old, XtNborderColor, (XtArgVal)old_border); + SetResource(cnew, XtNborderColor, (XtArgVal)new_border); +} + +/* + * Function: + * SetResourceByName + * + * Parameters: + * shell - shell widget of the popup + * name - name of the child + * res_name - name of the resource + * value - value of the resource + * + * Description: + * Sets a resource in any of the dialog children given + * name of the child and the shell widget of the dialog. + * + * Returns: + * True if sucessful + */ +static Bool +SetResourceByName(Widget shell, char *name, char *res_name, XtArgVal value) +{ + Widget temp_widget; + char buf[BUFSIZ]; + + snprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, name); + + if ((temp_widget = XtNameToWidget(shell, buf)) != NULL) { + SetResource(temp_widget, res_name, value); + return (True); + } + return (False); +} + +/* + * Function: + * SetResource + * + * Parameters: + * w - widget + * res_name - name of the resource + * value - value of the resource + * + * Description: + * Sets a resource in a widget + */ +static void +SetResource(Widget w, char *res_name, XtArgVal value) +{ + Arg args[1]; + + XtSetArg(args[0], res_name, value); + XtSetValues( w, args, 1); +} + +/* + * Function: + * GetString{Raw} + * + * Parameters: + * text - text widget whose string we will get + * + * Description: + * Gets the value for the string in the popup. + * + * Returns: + * GetString: the string as a MB + * GetStringRaw: the exact buffer contents suitable for a search + */ +static String +GetString(Widget text) +{ + String string; + Arg args[1]; + + XtSetArg(args[0], XtNstring, &string); + XtGetValues(text, args, 1); + + return (string); +} + +static String +GetStringRaw(Widget tw) +{ + TextWidget ctx = (TextWidget)tw; + XawTextPosition last; + + last = XawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight, + ctx->text.mult, True); + return (_XawTextGetText(ctx, 0, last)); +} + +/* + * Function: + * CenterWidgetOnPoint + * + * Parameters: + * w - shell widget + * event - event containing the location of the point + * + * Description: + * Centers a shell widget on a point relative to the root window. + * + * Note: + * The widget is not allowed to go off the screen + */ +static void +CenterWidgetOnPoint(Widget w, XEvent *event) +{ + Arg args[3]; + Cardinal num_args; + Dimension width, height, b_width; + Position x, y, max_x, max_y; + + if (event != NULL) { + switch (event->type) { + case ButtonPress: + case ButtonRelease: + x = event->xbutton.x_root; + y = event->xbutton.y_root; + break; + case KeyPress: + case KeyRelease: + x = event->xkey.x_root; + y = event->xkey.y_root; + break; + default: + return; + } + } + else + return; + + num_args = 0; + XtSetArg(args[num_args], XtNwidth, &width); num_args++; + XtSetArg(args[num_args], XtNheight, &height); num_args++; + XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++; + XtGetValues(w, args, num_args); + + width += b_width << 1; + height += b_width << 1; + + x -= (Position)(width >> 1); + if (x < 0) + x = 0; + if (x > (max_x = (Position)(XtScreen(w)->width - width))) + x = max_x; + + y -= (Position)(height >> 1); + if (y < 0) + y = 0; + if (y > (max_y = (Position)(XtScreen(w)->height - height))) + y = max_y; + + num_args = 0; + XtSetArg(args[num_args], XtNx, x); num_args++; + XtSetArg(args[num_args], XtNy, y); num_args++; + XtSetValues(w, args, num_args); +} + +/* + * Function: + * CreateDialog + * + * Parameters: + * parent - parent of the dialog - the main text widget + * ptr - initial_string for the dialog + * name - name of the dialog + * func - function to create the children of the dialog + * + * Returns: + * Popup shell of the dialog + * + * Note: + * The function argument is passed the following arguments: + * form - from widget that is the dialog + * ptr - initial string for the dialog's text widget + * parent - parent of the dialog - the main text widget + */ +static Widget +CreateDialog(Widget parent, String ptr, String name, AddFunc func) +{ + Widget popup, form; + Arg args[5]; + Cardinal num_args; + + num_args = 0; + XtSetArg(args[num_args], XtNiconName, name); num_args++; + XtSetArg(args[num_args], XtNgeometry, NULL); num_args++; + XtSetArg(args[num_args], XtNallowShellResize, True); num_args++; + XtSetArg(args[num_args], XtNtransientFor, GetShell(parent));num_args++; + popup = XtCreatePopupShell(name, transientShellWidgetClass, + parent, args, num_args); + + form = XtCreateManagedWidget(FORM_NAME, formWidgetClass, popup, NULL, 0); + XtManageChild (form); + + (*func)(form, ptr, parent); + + return (popup); +} + +/* + * Function + * GetShell + * nearest shell widget. + * + * Parameters: + * w - widget whose parent shell should be returned + * + * Returns: + * The shell widget among the ancestors of w that is the + * fewest levels up in the widget hierarchy. + * + * Description: + * Walks up the widget hierarchy to find the topmost shell widget. + */ +static Widget +GetShell(Widget w) +{ + while (w != NULL && !XtIsShell(w)) + w = XtParent(w); + + return (w); +} + +static Bool +InParams(String str, String *p, unsigned int n) +{ + unsigned int i; + + for (i = 0; i < n; p++, i++) + if (!XmuCompareISOLatin1(*p, str)) + return (True); + return (False); +} + +static char *WM_DELETE_WINDOW = "WM_DELETE_WINDOW"; + +static void +WMProtocols(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + Atom wm_delete_window; + Atom wm_protocols; + + wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, True); + wm_protocols = XInternAtom(XtDisplay(w), "WM_PROTOCOLS", True); + + /* Respond to a recognized WM protocol request if + * event type is ClientMessage and no parameters are passed, or + * event type is ClientMessage and event data is matched to parameters, or + * event type isn't ClientMessage and parameters make a request + */ +#define DO_DELETE_WINDOW InParams(WM_DELETE_WINDOW, params, *num_params) + + if ((event->type == ClientMessage + && event->xclient.message_type == wm_protocols + && event->xclient.data.l[0] == wm_delete_window + && (*num_params == 0 || DO_DELETE_WINDOW)) + || (event->type != ClientMessage && DO_DELETE_WINDOW)) { +#undef DO_DELETE_WINDOW + Widget cancel; + char descendant[DISMISS_NAME_LEN + 2]; + + snprintf(descendant, sizeof(descendant), "*%s", DISMISS_NAME); + cancel = XtNameToWidget(w, descendant); + if (cancel) + XtCallCallbacks(cancel, XtNcallback, NULL); + } +} + +static void +SetWMProtocolTranslations(Widget w) +{ + static XtTranslations compiled_table; + static XtAppContext *app_context_list; + static Cardinal list_size; + + unsigned int i; + XtAppContext app_context; + Atom wm_delete_window; + + app_context = XtWidgetToApplicationContext(w); + + /* parse translation table once */ + if (!compiled_table) + compiled_table = + XtParseTranslationTable("WM_PROTOCOLS:XawWMProtocols()\n"); + + /* add actions once per application context */ + for (i = 0; i < list_size && app_context_list[i] != app_context; i++) + ; + if (i == list_size) { + XtActionsRec actions[1]; + + actions[0].string = "XawWMProtocols"; + actions[0].proc = WMProtocols; + list_size++; + app_context_list = (XtAppContext *)XtRealloc + ((char *)app_context_list, list_size * sizeof(XtAppContext)); + XtAppAddActions(app_context, actions, 1); + app_context_list[i] = app_context; + } + + /* establish communication between the window manager and each shell */ + XtAugmentTranslations(w, compiled_table); + wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, False); + (void)XSetWMProtocols(XtDisplay(w), XtWindow(w), &wm_delete_window, 1); +} diff --git a/src/TextSink.c b/src/TextSink.c new file mode 100644 index 0000000..333701b --- /dev/null +++ b/src/TextSink.c @@ -0,0 +1,1828 @@ +/* + +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* + * Author: Chris Peterson, MIT X Consortium. + * + * Much code taken from X11R3 AsciiSink. + */ + +/* + * TextSink.c - TextSink object. (For use with the text widget). + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "Private.h" + +/* + * Prototypes + */ +static void XawTextSinkClassPartInitialize(WidgetClass); +static void XawTextSinkInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawTextSinkDestroy(Widget); +static Boolean XawTextSinkSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +static int MaxLines(Widget, unsigned int); +static int MaxHeight(Widget, int); +static void DisplayText(Widget, int, int, XawTextPosition, XawTextPosition, + Bool); +static void InsertCursor(Widget, int, int, XawTextInsertState); +static void ClearToBackground(Widget, int, int, unsigned int, unsigned int); +static void FindPosition(Widget, XawTextPosition, int, int, Bool, + XawTextPosition*, int*, int*); +static void FindDistance(Widget, XawTextPosition, int, XawTextPosition, int*, + XawTextPosition*, int*); +static void Resolve(Widget, XawTextPosition, int, int, XawTextPosition*); +static void SetTabs(Widget, int, short*); +static void GetCursorBounds(Widget, XRectangle*); + +#ifndef OLDXAW +static Boolean CvtStringToPropertyList(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Boolean CvtPropertyListToString(Display*, XrmValue*, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static Bool BeginPaint(Widget); +static Bool EndPaint(Widget); +static void SetXlfdDefaults(Display*, XawTextProperty*); +#endif + +/* + * External + */ +void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned); +void _XawTextSinkDisplayText(Widget, int, int, XawTextPosition, XawTextPosition, + Bool); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(TextSinkRec, text_sink.field) +static XtResource resources[] = { + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(foreground), + XtRString, + XtDefaultForeground + }, + { + XtNbackground, + XtCBackground, + XtRPixel, + sizeof(Pixel), + offset(background), + XtRString, + XtDefaultBackground + }, +#ifndef OLDXAW + { + XtNcursorColor, + XtCColor, + XtRPixel, + sizeof(Pixel), + offset(cursor_color), + XtRString, + XtDefaultForeground + }, + { + XawNtextProperties, + XawCTextProperties, + XawRTextProperties, + sizeof(XawTextPropertyList*), + offset(properties), + XtRImmediate, + NULL + }, +#endif +}; +#undef offset + +#ifndef OLDXAW +static TextSinkExtRec extension_rec = { + NULL, /* next_extension */ + NULLQUARK, /* record_type */ + 1, /* version */ + sizeof(TextSinkExtRec), /* record_size */ + BeginPaint, + NULL, + NULL, + EndPaint +}; + +static XrmQuark Qdefault; +#endif + +#define Superclass (&objectClassRec) +TextSinkClassRec textSinkClassRec = { + /* object */ + { + (WidgetClass)Superclass, /* superclass */ + "TextSink", /* class_name */ + sizeof(TextSinkRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + XawTextSinkClassPartInitialize, /* class_part_initialize */ + False, /* class_inited */ + XawTextSinkInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* obj1 */ + NULL, /* obj2 */ + 0, /* obj3 */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* obj4 */ + False, /* obj5 */ + False, /* obj6 */ + False, /* obj7 */ + XawTextSinkDestroy, /* destroy */ + NULL, /* obj8 */ + NULL, /* obj9 */ + XawTextSinkSetValues, /* set_values */ + NULL, /* set_values_hook */ + NULL, /* obj10 */ + NULL, /* get_values_hook */ + NULL, /* obj11 */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* obj12 */ + NULL, /* obj13 */ + NULL, /* obj14 */ + NULL, /* extension */ + }, + /* text_sink */ + { + DisplayText, /* DisplayText */ + InsertCursor, /* InsertCursor */ + ClearToBackground, /* ClearToBackground */ + FindPosition, /* FindPosition */ + FindDistance, /* FindDistance */ + Resolve, /* Resolve */ + MaxLines, /* MaxLines */ + MaxHeight, /* MaxHeight */ + SetTabs, /* SetTabs */ + GetCursorBounds, /* GetCursorBounds */ + }, +}; + +WidgetClass textSinkObjectClass = (WidgetClass)&textSinkClassRec; + +/* + * Implementation + */ +static void +XawTextSinkClassPartInitialize(WidgetClass wc) +{ + TextSinkObjectClass t_src, superC; +#ifndef OLDXAW + static XtConvertArgRec CvtArgs[] = { + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.self), + sizeof(Widget)}, + }; +#endif + + t_src = (TextSinkObjectClass) wc; + superC = (TextSinkObjectClass) t_src->object_class.superclass; + +#ifndef OLDXAW + extension_rec.record_type = XrmPermStringToQuark("TextSink"); + extension_rec.next_extension = (XtPointer)t_src->text_sink_class.extension; + t_src->text_sink_class.extension = &extension_rec; + + Qdefault = XrmPermStringToQuark("default"); +#endif + + /* + * We don't need to check for null super since we'll get to TextSink + * eventually. + */ + if (t_src->text_sink_class.DisplayText == XtInheritDisplayText) + t_src->text_sink_class.DisplayText = + superC->text_sink_class.DisplayText; + + if (t_src->text_sink_class.InsertCursor == XtInheritInsertCursor) + t_src->text_sink_class.InsertCursor = + superC->text_sink_class.InsertCursor; + + if (t_src->text_sink_class.ClearToBackground== XtInheritClearToBackground) + t_src->text_sink_class.ClearToBackground = + superC->text_sink_class.ClearToBackground; + + if (t_src->text_sink_class.FindPosition == XtInheritFindPosition) + t_src->text_sink_class.FindPosition = + superC->text_sink_class.FindPosition; + + if (t_src->text_sink_class.FindDistance == XtInheritFindDistance) + t_src->text_sink_class.FindDistance = + superC->text_sink_class.FindDistance; + + if (t_src->text_sink_class.Resolve == XtInheritResolve) + t_src->text_sink_class.Resolve = + superC->text_sink_class.Resolve; + + if (t_src->text_sink_class.MaxLines == XtInheritMaxLines) + t_src->text_sink_class.MaxLines = + superC->text_sink_class.MaxLines; + + if (t_src->text_sink_class.MaxHeight == XtInheritMaxHeight) + t_src->text_sink_class.MaxHeight = + superC->text_sink_class.MaxHeight; + + if (t_src->text_sink_class.SetTabs == XtInheritSetTabs) + t_src->text_sink_class.SetTabs = + superC->text_sink_class.SetTabs; + + if (t_src->text_sink_class.GetCursorBounds == XtInheritGetCursorBounds) + t_src->text_sink_class.GetCursorBounds = + superC->text_sink_class.GetCursorBounds; + +#ifndef OLDXAW + XtSetTypeConverter(XtRString, XawRTextProperties, CvtStringToPropertyList, + &CvtArgs[0], XtNumber(CvtArgs), XtCacheNone, NULL); + XtSetTypeConverter(XawRTextProperties, XtRString, CvtPropertyListToString, + NULL, 0, XtCacheNone, NULL); +#endif +} + +/* + * Function: + * XawTextSinkInitialize + * + * Parameters: + * request - requested and new values for the object instance + * cnew - "" + * + * Description: + * Initializes the TextSink Object. + */ +/*ARGSUSED*/ +static void +XawTextSinkInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + TextSinkObject sink = (TextSinkObject)cnew; + + sink->text_sink.tab_count = 0; /* Initialize the tab stops. */ + sink->text_sink.tabs = NULL; + sink->text_sink.char_tabs = NULL; +#ifndef OLDXAW + sink->text_sink.paint = NULL; +#endif +} + +/* + * Function: + * XawTextSinkDestroy + * + * Parameters: + * w - TextSink Object + * + * Description: + * This function cleans up when the object is destroyed. + */ +static void +XawTextSinkDestroy(Widget w) +{ + TextSinkObject sink = (TextSinkObject) w; + + XtFree((char *)sink->text_sink.tabs); + XtFree((char *)sink->text_sink.char_tabs); +} + +/* + * Function: + * XawTextSinkSetValues + * + * Parameters: + * current - current state of the object + * request - what was requested + * cnew - what the object will become + * + * Description: + * Sets the values for the TextSink. + * + * Returns: + * True if redisplay is needed + */ +/*ARGSUSED*/ +static Boolean +XawTextSinkSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + TextSinkObject w = (TextSinkObject)cnew; + TextSinkObject old_w = (TextSinkObject)current; + + if (w->text_sink.foreground != old_w->text_sink.foreground) + ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; + + return (False); +} + +/* + * Function: + * DisplayText + * + * Parameters: + * w - TextSink Object + * x - location to start drawing text + * y - "" + * pos1 - location of starting and ending points in the text buffer + * pos2 - "" + * highlight - hightlight this text? + * + * Description: + * Stub function that in subclasses will display text. + */ +/*ARGSUSED*/ +static void +DisplayText(Widget w, int x, int y, + XawTextPosition pos1, XawTextPosition pos2, Bool highlight) +{ + return; +} + +/* + * Function: + * InsertCursor + * + * Parameters: + * w - TextSink Object + * x - location for the cursor + * y - "" + * state - whether to turn the cursor on, or off + * + * Description: + * Places the InsertCursor. + */ +/*ARGSUSED*/ +static void +InsertCursor(Widget w, int x, int y, XawTextInsertState state) +{ + return; +} + +/* + * Function: + * ClearToBackground + * + * Parameters: + * w - TextSink Object + * x - location of area to clear + * y - "" + * width - size of area to clear + * height - "" + * + * Description: + * Clears a region of the sink to the background color. + */ +/*ARGSUSED*/ +static void +ClearToBackground(Widget w, int x, int y, + unsigned int width, unsigned int height) +{ + /* + * Don't clear in height or width are zero + * XClearArea() has special semantic for these values + */ + TextWidget xaw = (TextWidget)XtParent(w); + Position x1, y1, x2, y2; + + x1 = XawMax(x, xaw->text.r_margin.left); + y1 = XawMax(y, xaw->text.r_margin.top); + x2 = XawMin(x + (int)width, (int)XtWidth(xaw) - xaw->text.r_margin.right); + y2 = XawMin(y + (int)height, (int)XtHeight(xaw) - xaw->text.r_margin.bottom); + + x = x1; + y = y1; + width = XawMax(0, x2 - x1); + height = XawMax(0, y2 - y1); + + if (height != 0 && width != 0) + XClearArea(XtDisplayOfObject(w), XtWindowOfObject(w), + x, y, width, height, False); +} + +/* + * Function: + * FindPosition + * + * Parameters: + * w - TextSink Object + * fromPos - reference position + * fromX - reference location + * width - width of section to paint text + * stopAtWordBreak - returned position is a word break? + * resPos - position found (return) + * resWidth - Width actually used (return) + * resHeight - Height actually used (return) + * + * Description: + * Finds a position in the text. + */ +/*ARGSUSED*/ +static void +FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width, + Bool stopAtWordBreak, XawTextPosition *resPos, + int *resWidth, int *resHeight) +{ + *resPos = fromPos; + *resHeight = *resWidth = 0; +} + +/* + * Function: + * FindDistance + * + * Parameters: + * w - TextSink Object + * fromPos - starting Position + * fromX - x location of starting Position + * toPos - end Position + * resWidth - Distance between fromPos and toPos + * resPos - Acutal toPos used + * resHeight - Height required by this text + * + * Description: + * Find the Pixel Distance between two text Positions. + */ +/*ARGSUSED*/ +static void +FindDistance(Widget w, XawTextPosition fromPos, int fromx, + XawTextPosition toPos, int *resWidth, + XawTextPosition *resPos, int *resHeight) +{ + *resWidth = *resHeight = 0; + *resPos = fromPos; +} + +/* + * Function: + * Resolve + * + * Parameters: + * w - TextSink Object + * pos - reference Position + * fromx - reference Location + * width - width to move + * resPos - resulting position + * + * Description: + * Resloves a location to a position. + */ +/*ARGSUSED*/ +static void +Resolve(Widget w, XawTextPosition pos, int fromx, int width, + XawTextPosition *resPos) +{ + *resPos = pos; +} + +/* + * Function: + * MaxLines + * + * Parameters: + * w - TextSink Object + * height - height to fit lines into + * + * Description: + * Finds the Maximum number of lines that will fit in a given height. + * + * Returns: + * Number of lines that will fit + */ +/*ARGSUSED*/ +static int +MaxLines(Widget w, unsigned int height) +{ + /* + * The fontset has gone down to descent Sink Widget, so + * the functions such MaxLines, SetTabs... are bound to the descent. + * + * by Li Yuhong, Jan. 15, 1991 + */ + return (0); +} + +/* + * Function: + * MaxHeight + * + * Parameters: + * w - TextSink Object + * lines - number of lines + * + * Description: + * Finds the Minium height that will contain a given number lines. + * + * Returns: + * the height + */ +/*ARGSUSED*/ +static int +MaxHeight(Widget w, int lines) +{ + return (0); +} + +/* + * Function: + * SetTabs + * + * Parameters: + * w - TextSink Object + * tab_count - the number of tabs in the list + * tabs - text positions of the tabs + * Description: + * Sets the Tab stops. + */ +/*ARGSUSED*/ +static void +SetTabs(Widget w, int tab_count, short *tabs) +{ + return; +} + +/* + * Function: + * GetCursorBounds + * + * Parameters: + * w - TextSinkObject. + * rect - X rectangle containing the cursor bounds + * + * Description: + * Finds the bounding box for the insert cursor (caret) + */ +/*ARGSUSED*/ +static void +GetCursorBounds(Widget w, XRectangle *rect) +{ + rect->x = rect->y = rect->width = rect->height = 0; +} + +/* + * Public Functions + */ +/* + * Function: + * XawTextSinkDisplayText + * + * Parameters: + * w - TextSink Object + * x - location to start drawing text + * y - "" + * pos1 - location of starting and ending points in the text buffer + * pos2 - "" + * highlight - hightlight this text? + */ +/*ARGSUSED*/ +void +XawTextSinkDisplayText(Widget w, +#if NeedWidePrototypes + int x, int y, +#else + Position x, Position y, +#endif + XawTextPosition pos1, XawTextPosition pos2, +#if NeedWidePrototypes + int highlight +#else + Boolean highlight +#endif +) +{ + _XawTextSinkDisplayText(w, x, y, pos1, pos2, highlight); +} + +void +_XawTextSinkDisplayText(Widget w, int x, int y, + XawTextPosition pos1, XawTextPosition pos2, + Bool highlight) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + (*cclass->text_sink_class.DisplayText)(w, x, y, pos1, pos2, highlight); +} + +/* + * Function: + * XawTextSinkInsertCursor + * + * Parameters: + * w - TextSink Object + * x - location for the cursor + * y - "" + * state - whether to turn the cursor on, or off + * + * Description: + * Places the InsertCursor. + */ +/*ARGSUSED*/ +void +#if NeedWidePrototypes +XawTextSinkInsertCursor(Widget w, int x, int y, int state) +#else +XawTextSinkInsertCursor(Widget w, Position x, Position y, XawTextInsertState state) +#endif +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + (*cclass->text_sink_class.InsertCursor)(w, x, y, state); +} + +/* + * Function: + * XawTextSinkClearToBackground + * + * Parameters: + * w - TextSink Object + * x - location of area to clear + * y - "" + * width - size of area to clear + * height - "" + * + * Description: + * Clears a region of the sink to the background color. + */ +/*ARGSUSED*/ +void +XawTextSinkClearToBackground(Widget w, +#if NeedWidePrototypes + int x, int y, + unsigned int width, unsigned int height +#else + Position x, Position y, + Dimension width, Dimension height +#endif +) +{ + _XawTextSinkClearToBackground(w, x, y, width, height); +} + +void +_XawTextSinkClearToBackground(Widget w, + int x, int y, + unsigned int width, unsigned int height) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + (*cclass->text_sink_class.ClearToBackground)(w, x, y, width, height); +} + +/* + * Function: + * XawTextSinkFindPosition + * + * Parameters: + * w - TextSink Object + * fromPos - reference position + * fromX - reference location + * width - width of section to paint text + * stopAtWordBreak - returned position is a word break? + * resPos - position found (return) + * resWidth - Width actually used (return) + * resHeight - Height actually used (return) + * + * Description: + * Finds a position in the text. + */ +/*ARGSUSED*/ +void +XawTextSinkFindPosition(Widget w, XawTextPosition fromPos, int fromx, int width, +#if NeedWidePrototypes + int stopAtWordBreak, +#else + Boolean stopAtWordBreak, +#endif + XawTextPosition *resPos, int *resWidth, int *resHeight) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + (*cclass->text_sink_class.FindPosition)(w, fromPos, fromx, width, + stopAtWordBreak, + resPos, resWidth, resHeight); +} + +/* + * Function: + * XawTextSinkFindDistance + * + * Parameters: + * w - TextSink Object + * fromPos - starting Position + * fromX - x location of starting Position + * toPos - end Position + * resWidth - Distance between fromPos and toPos + * resPos - Acutal toPos used + * resHeight - Height required by this text + * + * Description: + * Find the Pixel Distance between two text Positions. + */ +/*ARGSUSED*/ +void +XawTextSinkFindDistance(Widget w, XawTextPosition fromPos, int fromx, + XawTextPosition toPos, int *resWidth, + XawTextPosition *resPos, int *resHeight) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + (*cclass->text_sink_class.FindDistance)(w, fromPos, fromx, toPos, + resWidth, resPos, resHeight); +} + +/* + * Function: + * XawTextSinkResolve + * + * Parameters: + * w - TextSink Object + * pos - reference Position + * fromx - reference Location + * width - width to move + * resPos - resulting position + * + * Description: + * Resloves a location to a position. + */ +/*ARGSUSED*/ +void +XawTextSinkResolve(Widget w, XawTextPosition pos, int fromx, int width, + XawTextPosition *resPos) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass) w->core.widget_class; + + (*cclass->text_sink_class.Resolve)(w, pos, fromx, width, resPos); +} + +/* + * Function: + * XawTextSinkMaxLines + * + * Parameters: + * w - TextSink Object + * height - height to fit lines into + * + * Description: + * Finds the Maximum number of lines that will fit in a given height. + * + * Returns: + * Number of lines that will fit + */ +/*ARGSUSED*/ +int +#if NeedWidePrototypes +XawTextSinkMaxLines(Widget w, unsigned int height) +#else +XawTextSinkMaxLines(Widget w, Dimension height) +#endif +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + return((*cclass->text_sink_class.MaxLines)(w, height)); +} + +/* + * Function: + * XawTextSinkMaxHeight + * + * Parameters: + * w - TextSink Object + * lines - number of lines + * + * Description: + * Finds the Minium height that will contain a given number lines. + * + * Returns: + * the height + */ +/*ARGSUSED*/ +int +XawTextSinkMaxHeight(Widget w, int lines) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + return((*cclass->text_sink_class.MaxHeight)(w, lines)); +} + +/* + * Function: + * XawTextSinkSetTabs + * + * Parameters: + * w - TextSink Object + * tab_count - the number of tabs in the list + * tabs - text positions of the tabs + * Description: + * Sets the Tab stops. + */ +void +XawTextSinkSetTabs(Widget w, int tab_count, int *tabs) +{ + if (tab_count > 0) { + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + short *char_tabs = (short*)XtMalloc((unsigned)tab_count * sizeof(short)); + short *tab, len = 0; + int i; + + for (i = tab_count, tab = char_tabs; i; i--) { + if ((short)*tabs > len) + *tab++ = (len = (short)*tabs++); + else { + tabs++; + --tab_count; + } + } + + if (tab_count > 0) + (*cclass->text_sink_class.SetTabs)(w, tab_count, char_tabs); + XtFree((char *)char_tabs); + } +} + +/* + * Function: + * XawTextSinkGetCursorBounds + * + * Parameters: + * w - TextSinkObject + * rect - X rectance containing the cursor bounds + * + * Description: + * Finds the bounding box for the insert cursor (caret). + */ +/*ARGSUSED*/ +void +XawTextSinkGetCursorBounds(Widget w, XRectangle *rect) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + (*cclass->text_sink_class.GetCursorBounds)(w, rect); +} + +#ifndef OLDXAW +Bool +XawTextSinkBeginPaint(Widget w) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + if (cclass->text_sink_class.extension->BeginPaint == NULL || + cclass->text_sink_class.extension->PreparePaint == NULL || + cclass->text_sink_class.extension->DoPaint == NULL || + cclass->text_sink_class.extension->EndPaint == NULL) + return (False); + + return ((*cclass->text_sink_class.extension->BeginPaint)(w)); +} + +static Bool +BeginPaint(Widget w) +{ + TextSinkObject sink = (TextSinkObject)w; + + if (sink->text_sink.paint != NULL) + return (False); + + sink->text_sink.paint = XtNew(XawTextPaintList); + sink->text_sink.paint->clip = XmuCreateArea(); + sink->text_sink.paint->hightabs = NULL; + sink->text_sink.paint->paint = NULL; + sink->text_sink.paint->bearings = NULL; + + return (True); +} + +void +XawTextSinkPreparePaint(Widget w, int y, int line, XawTextPosition from, + XawTextPosition to, Bool highlight) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + (*cclass->text_sink_class.extension->PreparePaint) + (w, y, line, from, to, highlight); +} + +#if 0 +/*ARGSUSED*/ +static void +PreparePaint(Widget w, int y, int line, XawTextPosition from, XawTextPosition to, + Bool highlight) +{ +} +#endif + +void +XawTextSinkDoPaint(Widget w) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + (*cclass->text_sink_class.extension->DoPaint)(w); +} + +#if 0 +/*ARGSUSED*/ +static void +DoPaint(Widget w) +{ +} +#endif + +Bool +XawTextSinkEndPaint(Widget w) +{ + TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; + + return ((*cclass->text_sink_class.extension->EndPaint)(w)); +} + +static Bool +EndPaint(Widget w) +{ + TextSinkObject sink = (TextSinkObject)w; + XawTextPaintStruct *paint, *next; + + if (sink->text_sink.paint == NULL) + return (False); + + XmuDestroyArea(sink->text_sink.paint->clip); + if (sink->text_sink.paint->hightabs) + XmuDestroyArea(sink->text_sink.paint->hightabs); + paint = sink->text_sink.paint->paint; + while (paint) { + next = paint->next; + if (paint->text) + XtFree((XtPointer)paint->text); + if (paint->backtabs) + XmuDestroyArea(paint->backtabs); + XtFree((XtPointer)paint); + paint = next; + } + + paint = sink->text_sink.paint->bearings; + while (paint) { + next = paint->next; + if (paint->text) + XtFree((XtPointer)paint->text); + XtFree((XtPointer)paint); + paint = next; + } + + XtFree((XtPointer)sink->text_sink.paint); + sink->text_sink.paint = NULL; + return (True); +} + +static XawTextPropertyList **prop_lists; +static Cardinal num_prop_lists; + +static int +bcmp_qident(_Xconst void *left, _Xconst void *right) +{ + return ((long)left - (*(XawTextProperty**)right)->identifier); +} + +static int +qcmp_qident(_Xconst void *left, _Xconst void *right) +{ + return ((*(XawTextProperty**)left)->identifier - + (*(XawTextProperty**)right)->identifier); +} + +static void +SetXlfdDefaults(Display *display, XawTextProperty *property) +{ + Atom atom = XInternAtom(display, "FONT", True); + unsigned long value; + char *str; + + if (XGetFontProperty(property->font, atom, &value)) { + char *xlfd = XGetAtomName(display, value); + + if (xlfd) { + char *sep = xlfd + 1; + char *name = sep; + + property->xlfd = XrmStringToQuark(xlfd); + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->foundry = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->family = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->weight = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->slant = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->setwidth = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->addstyle = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->pixel_size = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->point_size = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->res_x = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->res_y = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->spacing = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->avgwidth = XrmStringToQuark(name); + name = sep; + + sep = strchr(sep, '-'); *sep++ = '\0'; + property->registry = XrmStringToQuark(name); + name = sep; + + property->encoding = XrmStringToQuark(name); + + XFree(xlfd); + } + } + + atom = XInternAtom(display, "UNDERLINE_THICKNESS", True); + if (XGetFontProperty(property->font, atom, &value) && + (str = XGetAtomName(display, value)) != NULL) { + property->underline_thickness = atoi(str); + XFree(str); + } + else { + /* XLFD says: + * CapStemWidth = average width of the stems of capitals + * if (UNDERLINE_THICKNESS undefined) then + * UNDERLINE_THICKNESS = CapStemWidth + * + * How do I know the value of CapStemWidth?? + */ + if (property->pixel_size != NULLQUARK) { + property->underline_thickness = + atoi(XrmQuarkToString(property->pixel_size)) / 10; + property->underline_thickness = + XawMax(1, property->underline_thickness); + } + else + property->underline_thickness = 1; + } + + atom = XInternAtom(display, "UNDERLINE_POSITION", True); + if (XGetFontProperty(property->font, atom, &value) && + (str = XGetAtomName(display, value)) != NULL) { + property->underline_position = atoi(str); + XFree(str); + } + else + /* XLFD says: + * if (UNDERLINE_POSITION undefined) then + * UNDERLINE_POSITION = ROUND((maximum_descent) / 2) + */ + property->underline_position = + property->font->max_bounds.descent >> 1; + + /* I am assuming xlfd does not consider that lines are + * centered in the path */ + property->underline_position += property->underline_thickness >> 1; + +} + +static void +DestroyTextPropertyList(XawTextPropertyList *list) +{ + int i; + + for (i = 0; i < list->num_properties; i++) { + if (list->properties[i]->font) + XFreeFont(DisplayOfScreen(list->screen), list->properties[i]->font); + XtFree((char*)list->properties[i]); + } + if (list->properties) + XtFree((char*)list->properties); + XtFree((char*)list); +} + +static XawTextProperty * +_XawTextSinkGetProperty(XawTextPropertyList *list, XrmQuark property) +{ + if (property != NULLQUARK && list && list->properties) { + XawTextProperty **ptr = (XawTextProperty**) + bsearch((void*)(long)property, + list->properties, list->num_properties, + sizeof(XawTextProperty*), bcmp_qident); + + if (ptr) + return (*ptr); + } + + return (NULL); +} + +XawTextProperty * +XawTextSinkGetProperty(Widget w, XrmQuark property) +{ + TextSinkObject sink = (TextSinkObject)w; + XawTextPropertyList *list = sink->text_sink.properties; + + return (_XawTextSinkGetProperty(list, property)); +} + +XawTextProperty * +XawTextSinkCopyProperty(Widget w, XrmQuark property) +{ + XawTextProperty *cur, *ret; + + if ((cur = XawTextSinkGetProperty(w, property)) == NULL) + cur = XawTextSinkGetProperty(w, Qdefault); + ret = (XawTextProperty*)XtCalloc(1, sizeof(XawTextProperty)); + if (cur) + memcpy(ret, cur, sizeof(XawTextProperty)); + ret->identifier = NULLQUARK; + ret->mask &= ~XAW_TPROP_FONT; + + return (ret); +} + +static XawTextProperty * +_XawTextSinkAddProperty(XawTextPropertyList *list, XawTextProperty *property, + Bool replace) +{ + XawTextProperty *result; + XColor color; + char identifier[1024]; + char foreground[16]; + char background[16]; + char *foundry, *family, *weight, *slant, *setwidth, *addstyle, *pixel_size, + *point_size, *res_x, *res_y, *spacing, *avgwidth, *registry, *encoding; + char *xlfd; + static char *asterisk = "*", *null = ""; + XrmQuark quark; + + if (list == NULL || property == NULL) + return (NULL); + + if (property->mask & XAW_TPROP_FOREGROUND) { + color.pixel = property->foreground; + XQueryColor(DisplayOfScreen(list->screen), list->colormap, &color); + snprintf(foreground, sizeof(foreground), "%04x%04x%04x", + color.red, color.green, color.blue); + } + else + strcpy(foreground, asterisk); + if (property->mask & XAW_TPROP_BACKGROUND) { + color.pixel = property->background; + XQueryColor(DisplayOfScreen(list->screen), list->colormap, &color); + snprintf(background, sizeof(background), "%04x%04x%04x", + color.red, color.green, color.blue); + } + else + strcpy(background, asterisk); + + if (property->xlfd_mask & XAW_TPROP_FOUNDRY) + foundry = XrmQuarkToString(property->foundry); + else + foundry = asterisk; + + /* use default, or what was requested */ + if (property->family != NULLQUARK) + family = XrmQuarkToString(property->family); + else + family = asterisk; + if (property->weight != NULLQUARK) + weight = XrmQuarkToString(property->weight); + else + weight = asterisk; + if (property->slant != NULLQUARK) { + slant = XrmQuarkToString(property->slant); + if (toupper(*slant) != 'R') + slant = asterisk; /* X defaults to italics, so, don't + care in resolving between `I' and `O' */ + } + else + slant = asterisk; + + if (property->xlfd_mask & XAW_TPROP_SETWIDTH) + setwidth = XrmQuarkToString(property->setwidth); + else + setwidth = asterisk; + if (property->xlfd_mask & XAW_TPROP_ADDSTYLE) + addstyle = XrmQuarkToString(property->addstyle); + else + addstyle = null; + + /* use default, or what was requested */ + if (!(property->mask & XAW_TPROP_POINTSIZE) && + property->pixel_size != NULLQUARK) + pixel_size = XrmQuarkToString(property->pixel_size); + else + pixel_size = asterisk; + + if (property->xlfd_mask & XAW_TPROP_POINTSIZE) + point_size = XrmQuarkToString(property->point_size); + else + point_size = asterisk; + if (property->xlfd_mask & XAW_TPROP_RESX) + res_x = XrmQuarkToString(property->res_x); + else + res_x = asterisk; + if (property->xlfd_mask & XAW_TPROP_RESY) + res_y = XrmQuarkToString(property->res_y); + else + res_y = asterisk; + if (property->xlfd_mask & XAW_TPROP_SPACING) + spacing = XrmQuarkToString(property->spacing); + else + spacing = asterisk; + if (property->xlfd_mask & XAW_TPROP_AVGWIDTH) + avgwidth = XrmQuarkToString(property->avgwidth); + else + avgwidth = asterisk; + + /* use default, or what that was requested */ + if (property->registry != NULLQUARK) + registry = XrmQuarkToString(property->registry); + else + registry = asterisk; + if (property->encoding != NULLQUARK) + encoding = XrmQuarkToString(property->encoding); + else + encoding = asterisk; + + if (replace) { + result = XtNew(XawTextProperty); + memcpy(result, property, sizeof(XawTextProperty)); + } + else + result = property; + + /* XXX should do the best to load a suitable font here */ + if (!(result->mask & XAW_TPROP_FONT)) { + snprintf(identifier, sizeof(identifier), + "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", + foundry, family, weight, slant, setwidth, addstyle, + pixel_size, point_size, res_x, res_y, spacing, avgwidth, + registry, encoding); + if ((result->font = XLoadQueryFont(DisplayOfScreen(list->screen), + identifier)) != NULL) { + result->mask |= XAW_TPROP_FONT; + SetXlfdDefaults(DisplayOfScreen(list->screen), result); + } + else + result->mask &= ~XAW_TPROP_FONT; + } + + if (result->font) + xlfd = XrmQuarkToString(result->xlfd); + else + xlfd = null; + + snprintf(identifier, sizeof(identifier), "%08lx%08lx%s%s%d%d%d%d%s", + property->mask, property->xlfd_mask, + foreground, background, + (result->mask & XAW_TPROP_UNDERLINE) != 0, + (result->mask & XAW_TPROP_OVERSTRIKE) != 0, + (result->mask & XAW_TPROP_SUBSCRIPT) != 0, + (result->mask & XAW_TPROP_SUPERSCRIPT) != 0, + xlfd); + + quark = XrmStringToQuark(identifier); + if (result->identifier == NULLQUARK) + result->identifier = quark; + result->code = quark; + + if ((property = _XawTextSinkGetProperty(list, result->identifier)) != NULL) { + if (result->font) + XFreeFont(DisplayOfScreen(list->screen), result->font); + if (replace) + XtFree((XtPointer)result); + + return (property); + } + + list->properties = (XawTextProperty**) + XtRealloc((XtPointer)list->properties, sizeof(XawTextProperty*) * + (list->num_properties + 1)); + list->properties[list->num_properties++] = result; + qsort((void*)list->properties, list->num_properties, + sizeof(XawTextProperty*), qcmp_qident); + + return (result); +} + +XawTextProperty * +XawTextSinkAddProperty(Widget w, XawTextProperty *property) +{ + TextSinkObject sink = (TextSinkObject)w; + XawTextPropertyList *list = sink->text_sink.properties; + + return (_XawTextSinkAddProperty(list, property, True)); +} + +XawTextProperty * +XawTextSinkCombineProperty(Widget w, + XawTextProperty *property, XawTextProperty *combine, + Bool override) +{ + if (property == NULL || combine == NULL) + return (property); + + if ((override || !(property->mask & XAW_TPROP_FOREGROUND)) && + (combine->mask & XAW_TPROP_FOREGROUND)) { + property->mask |= XAW_TPROP_FOREGROUND; + property->foreground = combine->foreground; + } + if ((override || !(property->mask & XAW_TPROP_BACKGROUND)) && + (combine->mask & XAW_TPROP_BACKGROUND)) { + property->mask |= XAW_TPROP_BACKGROUND; + property->background = combine->background; + } + if ((override || !(property->mask & XAW_TPROP_FPIXMAP)) && + (combine->mask & XAW_TPROP_FPIXMAP)) { + property->mask |= XAW_TPROP_FPIXMAP; + property->foreground_pixmap = combine->foreground_pixmap; + } + if ((override || !(property->mask & XAW_TPROP_BPIXMAP)) && + (combine->mask & XAW_TPROP_BPIXMAP)) { + property->mask |= XAW_TPROP_BPIXMAP; + property->background_pixmap = combine->background_pixmap; + } + if (combine->mask & XAW_TPROP_UNDERLINE) + property->mask |= XAW_TPROP_UNDERLINE; + if (combine->mask & XAW_TPROP_OVERSTRIKE) + property->mask |= XAW_TPROP_OVERSTRIKE; + if ((override || !(property->mask & XAW_TPROP_SUPERSCRIPT)) && + (combine->mask & XAW_TPROP_SUBSCRIPT)) + property->mask |= XAW_TPROP_SUBSCRIPT; + if ((property->mask & XAW_TPROP_SUBSCRIPT) && + (combine->mask & XAW_TPROP_SUPERSCRIPT)) + property->mask |= XAW_TPROP_SUPERSCRIPT; + if ((override || !(property->xlfd_mask & XAW_TPROP_FOUNDRY)) && + (combine->xlfd_mask & XAW_TPROP_FOUNDRY)) { + property->xlfd_mask |= XAW_TPROP_FOUNDRY; + property->foundry = combine->foundry; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_FAMILY)) && + (combine->xlfd_mask & XAW_TPROP_FAMILY)) { + property->xlfd_mask |= XAW_TPROP_FAMILY; + property->family = combine->family; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_WEIGHT)) && + (combine->xlfd_mask & XAW_TPROP_WEIGHT)) { + property->xlfd_mask |= XAW_TPROP_WEIGHT; + property->weight = combine->weight; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_SLANT)) && + (combine->xlfd_mask & XAW_TPROP_SLANT)) { + property->xlfd_mask |= XAW_TPROP_SLANT; + property->slant = combine->slant; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_SETWIDTH)) && + (combine->xlfd_mask & XAW_TPROP_SETWIDTH)) { + property->xlfd_mask |= XAW_TPROP_SETWIDTH; + property->setwidth = combine->setwidth; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_ADDSTYLE)) && + (combine->xlfd_mask & XAW_TPROP_ADDSTYLE)) { + property->xlfd_mask |= XAW_TPROP_ADDSTYLE; + property->addstyle = combine->addstyle; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_PIXELSIZE)) && + (combine->xlfd_mask & XAW_TPROP_PIXELSIZE)) { + property->xlfd_mask |= XAW_TPROP_PIXELSIZE; + property->pixel_size = combine->pixel_size; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_POINTSIZE)) && + (combine->xlfd_mask & XAW_TPROP_POINTSIZE)) { + property->xlfd_mask |= XAW_TPROP_POINTSIZE; + property->point_size = combine->point_size; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_RESX)) && + (combine->xlfd_mask & XAW_TPROP_RESX)) { + property->xlfd_mask |= XAW_TPROP_RESX; + property->res_x = combine->res_x; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_RESY)) && + (combine->xlfd_mask & XAW_TPROP_RESY)) { + property->xlfd_mask |= XAW_TPROP_RESY; + property->res_y = combine->res_y; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_SPACING)) && + (combine->xlfd_mask & XAW_TPROP_SPACING)) { + property->xlfd_mask |= XAW_TPROP_SPACING; + property->spacing = combine->spacing; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_AVGWIDTH)) && + (combine->xlfd_mask & XAW_TPROP_AVGWIDTH)) { + property->xlfd_mask |= XAW_TPROP_AVGWIDTH; + property->avgwidth = combine->avgwidth; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_REGISTRY)) && + (combine->xlfd_mask & XAW_TPROP_REGISTRY)) { + property->xlfd_mask |= XAW_TPROP_REGISTRY; + property->registry = combine->registry; + } + if ((override || !(property->xlfd_mask & XAW_TPROP_ENCODING)) && + (combine->xlfd_mask & XAW_TPROP_ENCODING)) { + property->xlfd_mask |= XAW_TPROP_ENCODING; + property->encoding = combine->encoding; + } + + return (property); +} + +/* + * The default property must be defined first, if the code is willing to + * combine properties. + */ +XawTextPropertyList * +XawTextSinkConvertPropertyList(String name, String spec, Screen *screen, + Colormap colormap, int depth) +{ + XrmQuark qname = XrmStringToQuark(name); + XawTextPropertyList **ptr = NULL; + XawTextPropertyList *propl, *prev = NULL; + XawTextProperty *def_prop = NULL; + String str, tok, tmp; + char buffer[BUFSIZ]; + + if (prop_lists) ptr = (XawTextPropertyList**) + bsearch((void*)(long)qname, prop_lists, num_prop_lists, + sizeof(XawTextPropertyList*), bcmp_qident); + if (ptr) { + propl = *ptr; + while (propl) { + prev = propl; + if (propl->screen == screen && + propl->colormap == colormap && + propl->depth == depth) + return (propl); + propl = propl->next; + } + } + + propl = XtNew(XawTextPropertyList); + propl->identifier = qname; + propl->screen = screen; + propl->colormap = colormap; + propl->depth = depth; + propl->next = NULL; + + if (prev) + prev->next = propl; + + propl->properties = NULL; + propl->num_properties = 0; + + str = XtNewString(spec); + for (tok = str; tok; tok = tmp) { + XawTextProperty *prop; + XawParams *params; + XrmQuark ident; + XawArgVal *argval; + XColor color, exact; + + if (def_prop == NULL && propl->num_properties) + def_prop = _XawTextSinkGetProperty(propl, Qdefault); + tmp = strchr(tok, ','); + if (tmp) { + *tmp = '\0'; + if (*++tmp == '\0') + tmp = NULL; + } + params = XawParseParamsString(tok); + ident = XrmStringToQuark(params->name); + if (ident == NULLQUARK) { + snprintf(buffer, sizeof(buffer), "Bad text property name \"%s\".", + params->name); + XtAppWarning(XtDisplayToApplicationContext + (DisplayOfScreen(screen)), buffer); + DestroyTextPropertyList(propl); + if (prev) + prev->next = NULL; + XawFreeParamsStruct(params); + return (NULL); + } + else if (_XawTextSinkGetProperty(propl, ident) != NULL) { + XawFreeParamsStruct(params); + continue; + } + + prop = (XawTextProperty*)XtCalloc(1, sizeof(XawTextProperty)); + prop->identifier = ident; + + if ((argval = XawFindArgVal(params, "font")) != NULL && + argval->value) { + + if ((prop->font = XLoadQueryFont(DisplayOfScreen(screen), + argval->value)) == NULL) { + snprintf(buffer, sizeof(buffer), "Cannot load font \"%s\".", + argval->value); + XtAppWarning(XtDisplayToApplicationContext + (DisplayOfScreen(screen)), buffer); + DestroyTextPropertyList(propl); + if (prev) + prev->next = NULL; + XawFreeParamsStruct(params); + return (NULL); + } + prop->mask |= XAW_TPROP_FONT; + SetXlfdDefaults(DisplayOfScreen(screen), prop); + } + /* fontset processing here */ + + if ((argval = XawFindArgVal(params, "foreground")) != NULL && + argval->value) { + if (!XAllocNamedColor(DisplayOfScreen(screen), colormap, + argval->value, &color, &exact)) { + snprintf(buffer, sizeof(buffer), + "Cannot allocate color \"%s\".", argval->value); + XtAppWarning(XtDisplayToApplicationContext + (DisplayOfScreen(screen)), buffer); + DestroyTextPropertyList(propl); + if (prev) + prev->next = NULL; + XawFreeParamsStruct(params); + return (NULL); + } + prop->foreground = color.pixel; + prop->mask |= XAW_TPROP_FOREGROUND; + } + if ((argval = XawFindArgVal(params, "background")) != NULL && + argval->value) { + if (!XAllocNamedColor(DisplayOfScreen(screen), colormap, + argval->value, &color, &exact)) { + snprintf(buffer, sizeof(buffer), + "Cannot allocate color \"%s\".", argval->value); + XtAppWarning(XtDisplayToApplicationContext + (DisplayOfScreen(screen)), buffer); + DestroyTextPropertyList(propl); + if (prev) + prev->next = NULL; + XawFreeParamsStruct(params); + return (NULL); + } + prop->background = color.pixel; + prop->mask |= XAW_TPROP_BACKGROUND; + } + /* foreground_pixmap and background_pixmap processing here */ + + if (XawFindArgVal(params, "underline")) + prop->mask |= XAW_TPROP_UNDERLINE; + if (XawFindArgVal(params, "overstrike")) + prop->mask |= XAW_TPROP_OVERSTRIKE; + + if (XawFindArgVal(params, "subscript")) + prop->mask |= XAW_TPROP_SUBSCRIPT; + else if (XawFindArgVal(params, "superscript")) + prop->mask |= XAW_TPROP_SUPERSCRIPT; + + /* xlfd */ + if ((argval = XawFindArgVal(params, "foundry")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_FOUNDRY; + prop->foundry = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "family")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_FAMILY; + prop->family = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "weight")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_WEIGHT; + prop->weight = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "slant")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_SLANT; + prop->slant = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "setwidth")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_SETWIDTH; + prop->setwidth = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "addstyle")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_ADDSTYLE; + prop->addstyle = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "pixelsize")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_PIXELSIZE; + prop->pixel_size = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "pointsize")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_POINTSIZE; + prop->point_size = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "resx")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_RESX; + prop->res_x = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "resy")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_RESY; + prop->res_y = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "spacing")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_SPACING; + prop->spacing = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "avgwidth")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_AVGWIDTH; + prop->avgwidth = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "registry")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_REGISTRY; + prop->registry = XrmStringToQuark(argval->value); + } + if ((argval = XawFindArgVal(params, "encoding")) != NULL && + argval->value) { + prop->xlfd_mask |= XAW_TPROP_ENCODING; + prop->encoding = XrmStringToQuark(argval->value); + } + + if (def_prop) + (void)XawTextSinkCombineProperty(NULL, prop, def_prop, False); + (void)_XawTextSinkAddProperty(propl, prop, False); + + XawFreeParamsStruct(params); + } + + prop_lists = (XawTextPropertyList**) + XtRealloc((XtPointer)prop_lists, sizeof(XawTextPropertyList*) * + (num_prop_lists + 1)); + prop_lists[num_prop_lists++] = propl; + qsort((void*)prop_lists, num_prop_lists, sizeof(XawTextPropertyList*), + qcmp_qident); + + XtFree(str); + + return (propl); +} + +/*ARGSUSED*/ +static Boolean +CvtStringToPropertyList(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + XawTextPropertyList *propl = NULL; + String name; + Widget w; + + if (*num_args != 1) { + XtAppWarningMsg(XtDisplayToApplicationContext(dpy), + "wrongParameters", "cvtStringToTextProperties", + "ToolkitError", + "String to textProperties conversion needs widget argument", + NULL, NULL); + return (False); + } + + w = *(Widget*)args[0].addr; + while (w && !XtIsWidget(w)) + w = XtParent(w); + + name = (String)(fromVal[0].addr); + + if (w) { + XawTextPropertyList **ptr = NULL; + if (prop_lists) ptr = (XawTextPropertyList**) + bsearch((void*)(long)XrmStringToQuark(name), + prop_lists, num_prop_lists, + sizeof(XawTextPropertyList*), bcmp_qident); + + if (ptr) { + Screen *screen = w->core.screen; + Colormap colormap = w->core.colormap; + int depth = w->core.depth; + + propl = *ptr; + while (propl) { + if (propl->screen == screen && + propl->colormap == colormap && + propl->depth == depth) + break; + propl = propl->next; + } + } + } + + if (!propl) { + XtDisplayStringConversionWarning(dpy, (String)fromVal->addr, + XawRTextProperties); + toVal->addr = NULL; + toVal->size = sizeof(XawTextPropertyList*); + return (False); + } + + if (toVal->addr != NULL) { + if (toVal->size < sizeof(XawTextPropertyList*)) { + toVal->size = sizeof(XawTextPropertyList*); + return (False); + } + *(XawTextPropertyList**)(toVal->addr) = propl; + } + else { + static XawTextPropertyList *static_val; + + static_val = propl; + toVal->addr = (XPointer)&static_val; + } + toVal->size = sizeof(XawTextProperty*); + + return (True); +} + +/*ARGSUSED*/ +static Boolean +CvtPropertyListToString(Display *dpy, XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + static char *buffer; + Cardinal size; + XawTextPropertyList *propl; + + propl = *(XawTextPropertyList**)fromVal[0].addr; + + buffer = XrmQuarkToString(propl->identifier); + size = strlen(buffer) + 1; + + if (toVal->addr != NULL) { + if (toVal->size < size) { + toVal->size = size; + return (False); + } + strcpy((char *)toVal->addr, buffer); + } + else + toVal->addr = buffer; + toVal->size = size; + + return (True); +} +#endif diff --git a/src/TextSrc.c b/src/TextSrc.c new file mode 100644 index 0000000..26ce474 --- /dev/null +++ b/src/TextSrc.c @@ -0,0 +1,2008 @@ +/* + +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* + * Author: Chris Peterson, MIT X Consortium. + * Much code taken from X11R3 String and Disk Sources. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "XawI18n.h" +#include "Private.h" + +#ifndef OLDXAW +#define UNDO_DEPTH 16384 + +#define ANCHORS_DIST 4096 /* default distance between anchors */ + +/* + * Types + */ +typedef struct { + XawTextPosition position; + char *buffer; + unsigned length; + unsigned refcount; + unsigned long format; +} XawTextUndoBuffer; + +typedef struct _XawTextUndoList XawTextUndoList; +struct _XawTextUndoList { + XawTextUndoBuffer *left, *right; + XawTextUndoList *undo, *redo; +}; + +struct _XawTextUndo { + XawTextUndoBuffer **undo; + unsigned num_undo; + XawTextUndoList *list, *pointer, *end_mark, *head; + unsigned num_list; + XawTextScanDirection dir; + XawTextUndoBuffer *l_save, *r_save; + XawTextUndoList *u_save; + XawTextUndoBuffer *l_no_change, *r_no_change; + int merge; + int erase; /* there are two types of erases */ +}; +#endif /* OLDXAW */ + +/* + * Class Methods + */ +static Boolean ConvertSelection(Widget, Atom*, Atom*, Atom*, XtPointer*, + unsigned long*, int*); +static XawTextPosition Read(Widget, XawTextPosition, XawTextBlock*, int); +static int Replace(Widget, XawTextPosition, XawTextPosition, XawTextBlock*); +static XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType, + XawTextScanDirection, int, Bool); +static XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection, + XawTextBlock*); +static void SetSelection(Widget, XawTextPosition, XawTextPosition, Atom); +static void XawTextSrcClassInitialize(void); +static void XawTextSrcClassPartInitialize(WidgetClass); +static void XawTextSrcInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawTextSrcDestroy(Widget); +static Boolean XawTextSrcSetValues(Widget, Widget, Widget, ArgList, Cardinal*); +/* + * Prototypes + */ +static void CvtStringToEditMode(XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr); +static Boolean CvtEditModeToString(Display*, XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr, XtPointer*); +#ifndef OLDXAW +static void FreeUndoBuffer(XawTextUndo*); +static void UndoGC(XawTextUndo*); +static void TellSourceChanged(TextSrcObject, XawTextPosition, XawTextPosition, + XawTextBlock*, int); +Bool _XawTextSrcUndo(TextSrcObject, XawTextPosition*); +Bool _XawTextSrcToggleUndo(TextSrcObject); +XawTextAnchor *_XawTextSourceFindAnchor(Widget, XawTextPosition); + +/* + * External + */ +void _XawSourceAddText(Widget, Widget); +void _XawSourceRemoveText(Widget, Widget, Bool); +Bool _XawTextSourceNewLineAtEOF(Widget); +void _XawSourceSetUndoErase(TextSrcObject, int); +void _XawSourceSetUndoMerge(TextSrcObject, Bool); +#endif /* OLDXAW */ + +/* + * Defined in Text.c + */ +char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition); +void _XawTextSourceChanged(Widget, XawTextPosition, XawTextPosition, + XawTextBlock*, int); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(TextSrcRec, textSrc.field) +static XtResource resources[] = { + { + XtNeditType, + XtCEditType, + XtREditMode, + sizeof(XawTextEditType), + offset(edit_mode), + XtRString, + "read" + }, +#ifndef OLDXAW + { + XtNcallback, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + offset(callback), + XtRCallback, + NULL + }, + { + XtNsourceChanged, + XtCChanged, + XtRBoolean, + sizeof(Boolean), + offset(changed), + XtRImmediate, + (XtPointer)False + }, + { + XtNenableUndo, + XtCUndo, + XtRBoolean, + sizeof(Boolean), + offset(enable_undo), + XtRImmediate, + (XtPointer)False + }, + { + XtNpropertyCallback, + XtCCallback, + XtRCallback, + sizeof(XtPointer), + offset(property_callback), + XtRCallback, + NULL + }, +#endif /* OLDXAW */ +}; +#undef offset + +#define Superclass (&objectClassRec) +TextSrcClassRec textSrcClassRec = { + /* object */ + { + (WidgetClass)Superclass, /* superclass */ + "TextSrc", /* class_name */ + sizeof(TextSrcRec), /* widget_size */ + XawTextSrcClassInitialize, /* class_initialize */ + XawTextSrcClassPartInitialize, /* class_part_initialize */ + False, /* class_inited */ + XawTextSrcInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* compress_motion */ + False, /* compress_exposure */ + False, /* compress_enterleave */ + False, /* visible_interest */ + XawTextSrcDestroy, /* destroy */ + NULL, /* resize */ + NULL, /* expose */ + XawTextSrcSetValues, /* set_values */ + NULL, /* set_values_hook */ + NULL, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + NULL, /* query_geometry */ + NULL, /* display_accelerator */ + NULL, /* extension */ + }, + /* text_src */ + { + Read, /* Read */ + Replace, /* Replace */ + Scan, /* Scan */ + Search, /* Search */ + SetSelection, /* SetSelection */ + ConvertSelection, /* ConvertSelection */ + }, +}; + +WidgetClass textSrcObjectClass = (WidgetClass)&textSrcClassRec; + +static XrmQuark QRead, QAppend, QEdit; +#ifndef OLDXAW +static char *SrcNL = "\n"; +static wchar_t SrcWNL[2]; +#endif + +/* + * Implementation + */ +static void +XawTextSrcClassInitialize(void) +{ + XawInitializeWidgetSet(); + +#ifndef OLDXAW + SrcWNL[0] = _Xaw_atowc(XawLF); + SrcWNL[1] = 0; +#endif + QRead = XrmPermStringToQuark(XtEtextRead); + QAppend = XrmPermStringToQuark(XtEtextAppend); + QEdit = XrmPermStringToQuark(XtEtextEdit); + XtAddConverter(XtRString, XtREditMode, CvtStringToEditMode, NULL, 0); + XtSetTypeConverter(XtREditMode, XtRString, CvtEditModeToString, NULL, 0, + XtCacheNone, NULL); +} + +static void +XawTextSrcClassPartInitialize(WidgetClass wc) +{ + TextSrcObjectClass t_src, superC; + + t_src = (TextSrcObjectClass)wc; + superC = (TextSrcObjectClass)t_src->object_class.superclass; + + /* + * We don't need to check for null super since we'll get to TextSrc + * eventually + */ + if (t_src->textSrc_class.Read == XtInheritRead) + t_src->textSrc_class.Read = superC->textSrc_class.Read; + + if (t_src->textSrc_class.Replace == XtInheritReplace) + t_src->textSrc_class.Replace = superC->textSrc_class.Replace; + + if (t_src->textSrc_class.Scan == XtInheritScan) + t_src->textSrc_class.Scan = superC->textSrc_class.Scan; + + if (t_src->textSrc_class.Search == XtInheritSearch) + t_src->textSrc_class.Search = superC->textSrc_class.Search; + + if (t_src->textSrc_class.SetSelection == XtInheritSetSelection) + t_src->textSrc_class.SetSelection = superC->textSrc_class.SetSelection; + + if (t_src->textSrc_class.ConvertSelection == XtInheritConvertSelection) + t_src->textSrc_class.ConvertSelection = + superC->textSrc_class.ConvertSelection; +} + +/*ARGSUSED*/ +static void +XawTextSrcInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ +#ifndef OLDXAW + TextSrcObject src = (TextSrcObject)cnew; + + if (src->textSrc.enable_undo) { + src->textSrc.undo = (XawTextUndo*)XtCalloc(1, sizeof(XawTextUndo)); + src->textSrc.undo->dir = XawsdLeft; + } + else + src->textSrc.undo = NULL; + src->textSrc.undo_state = False; + if (XtIsSubclass(XtParent(cnew), textWidgetClass)) { + src->textSrc.text = (WidgetList)XtMalloc(sizeof(Widget*)); + src->textSrc.text[0] = XtParent(cnew); + src->textSrc.num_text = 1; + } + else { + src->textSrc.text = NULL; + src->textSrc.num_text = 0; + } + + src->textSrc.anchors = NULL; + src->textSrc.num_anchors = 0; + (void)XawTextSourceAddAnchor(cnew, 0); +#endif /* OLDXAW */ +} + +static void +XawTextSrcDestroy(Widget w) +{ +#ifndef OLDXAW + TextSrcObject src = (TextSrcObject)w; + + if (src->textSrc.enable_undo) { + FreeUndoBuffer(src->textSrc.undo); + XtFree((char*)src->textSrc.undo); + } + XtFree((char*)src->textSrc.text); + + if (src->textSrc.num_anchors) { + XawTextEntity *entity, *enext; + int i; + + for (i = 0; i < src->textSrc.num_anchors; i++) { + entity = src->textSrc.anchors[i]->entities; + while (entity) { + enext = entity->next; + XtFree((XtPointer)entity); + entity = enext; + } + XtFree((XtPointer)src->textSrc.anchors[i]); + } + XtFree((XtPointer)src->textSrc.anchors); + } +#endif /* OLDXAW */ +} + +/*ARGSUSED*/ +static Boolean +XawTextSrcSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ +#ifndef OLDXAW + TextSrcObject oldtw = (TextSrcObject)current; + TextSrcObject newtw = (TextSrcObject)cnew; + + if (oldtw->textSrc.enable_undo != newtw->textSrc.enable_undo) { + if (newtw->textSrc.enable_undo) { + newtw->textSrc.undo = (XawTextUndo*) + XtCalloc(1, sizeof(XawTextUndo)); + newtw->textSrc.undo->dir = XawsdLeft; + } + else { + FreeUndoBuffer(newtw->textSrc.undo); + XtFree((char*)newtw->textSrc.undo); + newtw->textSrc.undo = NULL; + } + } + if (oldtw->textSrc.changed != newtw->textSrc.changed) { + if (newtw->textSrc.enable_undo) { + if (newtw->textSrc.undo->list) { + newtw->textSrc.undo->l_no_change = + newtw->textSrc.undo->list->left; + newtw->textSrc.undo->r_no_change = + newtw->textSrc.undo->list->right; + } + else + newtw->textSrc.undo->l_no_change = + newtw->textSrc.undo->r_no_change = NULL; + } + } +#endif /* OLDXAW */ + return (False); +} + +/* + * Function: + * Read + * + * Parameters: + * w - TextSrc Object + * pos - position of the text to retreive + * text - text block that will contain returned text + * length - maximum number of characters to read + * + * Description: + * This function reads the source. + * + * Returns: + * The character position following the retrieved text. + */ +/*ARGSUSED*/ +static XawTextPosition +Read(Widget w, XawTextPosition pos, XawTextBlock *text, int length) +{ + return ((XawTextPosition)0); +} + +/* + * Function: + * Replace + * + * Parameters: + * src - Text Source Object + * startPos - ends of text that will be removed + * endPos - "" + * text - new text to be inserted into buffer at startPos + * + * Description: + * Replaces a block of text with new text. + */ +/*ARGSUSED*/ +static int +Replace(Widget w, XawTextPosition startPos, XawTextPosition endPos, + XawTextBlock *text) +{ + return (XawEditError); +} + +/* + * Function: + * Scan + * + * Parameters: + * w - TextSrc Object + * position - position to start scanning + * type - type of thing to scan for + * dir - direction to scan + * count - which occurance if this thing to search for + * include - whether or not to include the character found in + * the position that is returned + * + * Description: + * Scans the text source for the number and type of item specified. + */ +/*ARGSUSED*/ +static XawTextPosition +Scan(Widget w, XawTextPosition position, XawTextScanType type, + XawTextScanDirection dir, int count, Bool include) +{ + return ((XawTextPosition)0); +} + +/* + * Function: + * Search + * + * Parameters: + * w - TextSource Object + * position - position to start searching + * dir - direction to search + * text - the text block to search for + * + * Description: + * Searchs the text source for the text block passed + */ +/*ARGSUSED*/ +static XawTextPosition +Search(Widget w, XawTextPosition position, XawTextScanDirection dir, + XawTextBlock *text) +{ + return (XawTextSearchError); +} + +/*ARGSUSED*/ +static Boolean +ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type, + XtPointer *value, unsigned long *length, int *format) +{ + return (False); +} + +/*ARGSUSED*/ +static void +SetSelection(Widget w, XawTextPosition left, XawTextPosition right, + Atom selection) +{ +} + +/*ARGSUSED*/ +static void +CvtStringToEditMode(XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal) +{ + static XawTextEditType editType; + XrmQuark q; + char name[7]; + + XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name)); + q = XrmStringToQuark(name); + + if (q == QRead) + editType = XawtextRead; + else if (q == QAppend) + editType = XawtextAppend; + else if (q == QEdit) + editType = XawtextEdit; + else { + toVal->size = 0; + toVal->addr = NULL; + XtStringConversionWarning((char *)fromVal->addr, XtREditMode); + } + toVal->size = sizeof(XawTextEditType); + toVal->addr = (XPointer)&editType; +} + +/*ARGSUSED*/ +static Boolean +CvtEditModeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal, + XtPointer *data) +{ + static String buffer; + Cardinal size; + + switch (*(XawTextEditType *)fromVal->addr) { + case XawtextRead: + buffer = XtEtextRead; + break; + case XawtextAppend: + buffer = XtEtextAppend; + break; + case XawtextEdit: + buffer = XtEtextEdit; + break; + default: + XawTypeToStringWarning(dpy, XtREditMode); + toVal->addr = NULL; + toVal->size = 0; + return (False); + } + + size = strlen(buffer) + 1; + if (toVal->addr != NULL) { + if (toVal->size < size) { + toVal->size = size; + return (False); + } + strcpy((char *)toVal->addr, buffer); + } + else + toVal->addr = (XPointer)buffer; + toVal->size = sizeof(String); + + return (True); +} + +#ifndef OLDXAW +Bool +_XawTextSourceNewLineAtEOF(Widget w) +{ + TextSrcObject src = (TextSrcObject)w; + XawTextBlock text; + + text.firstPos = 0; + if ((text.format = src->textSrc.text_format) == XawFmt8Bit) + text.ptr = SrcNL; + else + text.ptr = (char*)SrcWNL; + text.length = 1; + + return (XawTextSourceSearch(w, XawTextSourceScan(w, 0, XawstAll, + XawsdRight, 1, True) - 1, + XawsdRight, &text) != XawTextSearchError); +} + +void +_XawSourceAddText(Widget source, Widget text) +{ + TextSrcObject src = (TextSrcObject)source; + Bool found = False; + Cardinal i; + + for (i = 0; i < src->textSrc.num_text; i++) + if (src->textSrc.text[i] == text) { + found = True; + break; + } + + if (!found) { + src->textSrc.text = (WidgetList) + XtRealloc((char*)src->textSrc.text, + sizeof(Widget) * (src->textSrc.num_text + 1)); + src->textSrc.text[src->textSrc.num_text++] = text; + } +} + +void +_XawSourceRemoveText(Widget source, Widget text, Bool destroy) +{ + TextSrcObject src = (TextSrcObject)source; + Bool found = False; + Cardinal i; + + if (src == NULL) + return; + + for (i = 0; i < src->textSrc.num_text; i++) + if (src->textSrc.text[i] == text) { + found = True; + break; + } + + if (found) { + if (--src->textSrc.num_text == 0) { + if (destroy) { + XtDestroyWidget(source); + return; + } + else { + XtFree((char*)src->textSrc.text); + src->textSrc.text = NULL; /* for realloc "magic" */ + } + } + else if (i < src->textSrc.num_text) + memmove(&src->textSrc.text[i], &src->textSrc.text[i + 1], + sizeof(Widget) * (src->textSrc.num_text - i)); + } +} +#endif /* OLDXAW */ + +/* + * Function: + * XawTextSourceRead + * + * Parameters: + * w - TextSrc Object + * pos - position of the text to retrieve + * text - text block that will contain returned text (return) + * length - maximum number of characters to read + * + * Description: + * This function reads the source. + * + * Returns: + * The number of characters read into the buffer + */ +XawTextPosition +XawTextSourceRead(Widget w, XawTextPosition pos, XawTextBlock *text, + int length) +{ + TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; + + return ((*cclass->textSrc_class.Read)(w, pos, text, length)); +} + +#ifndef OLDXAW +static void +TellSourceChanged(TextSrcObject src, XawTextPosition left, + XawTextPosition right, XawTextBlock *block, int lines) +{ + Cardinal i; + + for (i = 0; i < src->textSrc.num_text; i++) + _XawTextSourceChanged(src->textSrc.text[i], left, right, block, lines); +} + +/* + * This function is required because there is no way to diferentiate + * if the first erase was generated by a backward-kill-char and the + * second by a forward-kill-char (or vice-versa) from XawTextSourceReplace. + * It is only possible to diferentiate after the second character is + * killed, but then, it is too late. + */ +void +_XawSourceSetUndoErase(TextSrcObject src, int value) +{ + if (src && src->textSrc.enable_undo) + src->textSrc.undo->erase = value; +} + +/* + * To diferentiate insert-char's separeted by cursor movements. + */ +void +_XawSourceSetUndoMerge(TextSrcObject src, Bool state) +{ + if (src && src->textSrc.enable_undo) + src->textSrc.undo->merge += state ? 1 : -1; +} +#endif /* OLDXAW */ + +/* + * Public Functions + */ +/* + * Function: + * XawTextSourceReplace + * + * Parameters: + * src - Text Source Object + * startPos - ends of text that will be removed + * endPos - "" + * text - new text to be inserted into buffer at startPos + * + * Description: + * Replaces a block of text with new text. + * + * Returns: + * XawEditError or XawEditDone. + */ +/*ARGSUSED*/ +int +XawTextSourceReplace(Widget w, XawTextPosition left, + XawTextPosition right, XawTextBlock *block) +{ + TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; +#ifndef OLDXAW + TextSrcObject src = (TextSrcObject)w; + XawTextUndoBuffer *l_state, *r_state; + XawTextUndoList *undo; + Bool enable_undo; + XawTextPosition start, end; + int i, error, lines = 0; + + if (src->textSrc.edit_mode == XawtextRead) + return (XawEditError); + + enable_undo = src->textSrc.enable_undo && src->textSrc.undo_state == False; + if (enable_undo) { + unsigned size, total; + + if (src->textSrc.undo->l_save) { + l_state = src->textSrc.undo->l_save; + src->textSrc.undo->l_save = NULL; + } + else + l_state = XtNew(XawTextUndoBuffer); + l_state->refcount = 1; + l_state->position = left; + if (left < right) { + Widget ctx = NULL; + + for (i = 0; i < src->textSrc.num_text; i++) + if (XtIsSubclass(src->textSrc.text[i], textWidgetClass)) { + ctx = src->textSrc.text[i]; + break; + } + l_state->buffer = _XawTextGetText((TextWidget)ctx, left, right); + l_state->length = right - left; + } + else { + l_state->length = 0; + l_state->buffer = NULL; + } + l_state->format = src->textSrc.text_format; + if (l_state->length == 1) { + if (l_state->format == XawFmtWide && + *(wchar_t*)l_state->buffer == *SrcWNL) { + XtFree(l_state->buffer); + l_state->buffer = (char*)SrcWNL; + } + else if (*l_state->buffer == '\n') { + XtFree(l_state->buffer); + l_state->buffer = SrcNL; + } + } + + if (src->textSrc.undo->r_save) { + r_state = src->textSrc.undo->r_save; + src->textSrc.undo->r_save = NULL; + } + else + r_state = XtNew(XawTextUndoBuffer); + r_state->refcount = 1; + r_state->position = left; + r_state->format = block->format; + size = block->format == XawFmtWide ? sizeof(wchar_t) : sizeof(char); + total = size * block->length; + r_state->length = block->length; + r_state->buffer = NULL; + if (total == size) { + if (r_state->format == XawFmtWide && + *(wchar_t*)block->ptr == *SrcWNL) + r_state->buffer = (char*)SrcWNL; + else if (*block->ptr == '\n') + r_state->buffer = SrcNL; + } + if (total && !r_state->buffer) { + r_state->buffer = XtMalloc(total); + memcpy(r_state->buffer, block->ptr, total); + } + + if (src->textSrc.undo->u_save) { + undo = src->textSrc.undo->u_save; + src->textSrc.undo->u_save = NULL; + } + else + undo = XtNew(XawTextUndoList); + undo->left = l_state; + undo->right = r_state; + undo->undo = src->textSrc.undo->list; + undo->redo = NULL; + } + else { + undo = NULL; + l_state = r_state = NULL; + } + +#define LARGE_VALUE 262144 /* 256 K */ + /* optimization, to avoid long delays recalculating the line number + * when editing huge files + */ + if (left > LARGE_VALUE) { + start = XawTextSourceScan(w, left, XawstEOL, XawsdLeft, 2, False); + for (i = 0; i < src->textSrc.num_text; i++) { + TextWidget tw = (TextWidget)src->textSrc.text[i]; + + if (left <= tw->text.lt.top && + left + block->length - (right - left) > tw->text.lt.top) + _XawTextBuildLineTable(tw, start, False); + } + } +#undef LARGE_VALUE + + start = left; + end = right; + while (start < end) { + start = XawTextSourceScan(w, start, XawstEOL, XawsdRight, 1, True); + if (start <= end) { + --lines; + if (start == XawTextSourceScan(w, 0, XawstAll, XawsdRight, 1, True)) { + lines += !_XawTextSourceNewLineAtEOF(w); + break; + } + } + } +#else + int error; +#endif /* OLDXAW */ + + error = (*cclass->textSrc_class.Replace)(w, left, right, block); + +#ifndef OLDXAW + if (error != XawEditDone) { + if (enable_undo) { + if (l_state->buffer) { + if (l_state->buffer != SrcNL && l_state->buffer != (char*)SrcWNL) + XtFree(l_state->buffer); + l_state->buffer = NULL; + } + src->textSrc.undo->l_save = l_state; + if (r_state->buffer) { + if (r_state->buffer != SrcNL && r_state->buffer != (char*)SrcWNL) + XtFree(r_state->buffer); + r_state->buffer = NULL; + } + src->textSrc.undo->r_save = r_state; + + src->textSrc.undo->u_save = undo; + } + } + else if (enable_undo) { + XawTextUndoList *list = src->textSrc.undo->list; + XawTextUndoBuffer *unl, *lnl; + int erase = undo->right->length == 0 && undo->left->length == 1 && list + && list->right->length == 0; + + if (erase) { + erase = list->left->position - 1 == undo->left->position ? -1 : + list->left->position == undo->left->position ? 1 : 0; + if (src->textSrc.undo->erase && erase != src->textSrc.undo->erase) + erase = 0; + else + src->textSrc.undo->erase = erase; + } + + if (erase) { + unl = l_state; + lnl = list->left; + } + else { + unl = r_state; + lnl = list ? list->right : NULL; + } + + /* Try to merge the undo buffers */ + if (src->textSrc.undo->merge > 0 && ((erase || + (list && ((list->left->length == 0 && undo->left->length == 0) || + (list->left->length == list->right->length && + undo->left->length == 1)) && + undo->right->length == 1 && + list->right->position + list->right->length + == undo->right->position)) + && src->textSrc.undo->pointer == list + && unl->format == list->right->format + && ((unl->format == XawFmt8Bit && unl->buffer[0] != XawLF) || + (unl->format == XawFmtWide && + *(wchar_t*)(unl->buffer) != _Xaw_atowc(XawLF))) + && ((lnl->format == XawFmt8Bit && lnl->buffer[0] != XawLF) || + (lnl->format == XawFmtWide && + *(wchar_t*)(lnl->buffer) != _Xaw_atowc(XawLF))))) { + unsigned size = lnl->format == XawFmtWide ? + sizeof(wchar_t) : sizeof(char); + + if (!erase) { + list->right->buffer = XtRealloc(list->right->buffer, + (list->right->length + 1) * size); + memcpy(list->right->buffer + list->right->length * size, + undo->right->buffer, size); + ++list->right->length; + XtFree(r_state->buffer); + } + else if (erase < 0) { + --list->left->position; + --list->right->position; + } + + src->textSrc.undo->l_save = l_state; + src->textSrc.undo->r_save = r_state; + src->textSrc.undo->u_save = undo; + + if (list->left->length) { + list->left->buffer = XtRealloc(list->left->buffer, + (list->left->length + 1) * size); + if (erase >= 0) + memcpy(list->left->buffer + list->left->length * size, + undo->left->buffer, size); + else { + /* use memmove, since strings overlap */ + memmove(list->left->buffer + size, list->left->buffer, + list->left->length * size); + memcpy(list->left->buffer, undo->left->buffer, size); + } + ++list->left->length; + if (l_state->buffer != SrcNL && l_state->buffer != (char*)SrcWNL) + XtFree(l_state->buffer); + } + + if (src->textSrc.undo->num_list >= UNDO_DEPTH) + UndoGC(src->textSrc.undo); + } + else { + src->textSrc.undo->undo = (XawTextUndoBuffer**) + XtRealloc((char*)src->textSrc.undo->undo, + (2 + src->textSrc.undo->num_undo) + * sizeof(XawTextUndoBuffer)); + src->textSrc.undo->undo[src->textSrc.undo->num_undo++] = l_state; + src->textSrc.undo->undo[src->textSrc.undo->num_undo++] = r_state; + + if (src->textSrc.undo->list) + src->textSrc.undo->list->redo = undo; + else + src->textSrc.undo->head = undo; + + src->textSrc.undo->merge = l_state->length <= 1 && + r_state->length <= 1; + + src->textSrc.undo->list = src->textSrc.undo->pointer = + src->textSrc.undo->end_mark = undo; + + if (++src->textSrc.undo->num_list >= UNDO_DEPTH) + UndoGC(src->textSrc.undo); + } + src->textSrc.undo->dir = XawsdLeft; + if (!src->textSrc.changed) { + src->textSrc.undo->l_no_change = src->textSrc.undo->list->right; + src->textSrc.undo->r_no_change = src->textSrc.undo->list->left; + src->textSrc.changed = True; + } + } + else if (!src->textSrc.enable_undo) + src->textSrc.changed = True; + + if (error == XawEditDone) { + XawTextPropertyInfo info; + XawTextAnchor *anchor; + + /* find anchor and index */ + /* XXX index (i) could be returned by XawTextSourceFindAnchor + * or similar function, to speed up */ + if ((anchor = XawTextSourceFindAnchor(w, left))) { + XawTextEntity *eprev, *entity, *enext; + XawTextPosition offset = 0, diff = block->length - (right - left); + + for (i = 0; i < src->textSrc.num_anchors; i++) + if (src->textSrc.anchors[i] == anchor) + break; + if (anchor->cache && anchor->position + anchor->cache->offset + + anchor->cache->length <= left) + eprev = entity = anchor->cache; + else + eprev = entity = anchor->entities; + while (entity) { + offset = anchor->position + entity->offset; + + if (offset > left) + break; + if (offset + entity->length > left) + break; + + eprev = entity; + entity = entity->next; + } + + /* try to do the right thing here (and most likely correct), but + * other code needs to check what was done */ + + /* adjust entity length */ + if (entity && offset <= left) { + if (offset + entity->length < right) + entity->length = left - offset + block->length; + else + entity->length += diff; + + if (entity->length == 0) { + enext = entity->next; + eprev->next = enext; + anchor->cache = NULL; + XtFree((XtPointer)entity); + if (entity == anchor->entities) { + if ((anchor->entities = enext) == NULL) { + eprev = NULL; + anchor = XawTextSourceRemoveAnchor(w, anchor); + entity = anchor ? anchor->entities : NULL; + } + else + eprev = entity = enext; + } + else + entity = enext; + } + else { + eprev = entity; + entity = entity->next; + } + } + + while (anchor) { + while (entity) { + offset = anchor->position + entity->offset + entity->length; + + if (offset > right) { + entity->length = XawMin(entity->length, offset - right); + goto exit_anchor_loop; + } + + enext = entity->next; + if (eprev) + eprev->next = enext; + XtFree((XtPointer)entity); + anchor->cache = NULL; + if (entity == anchor->entities) { + eprev = NULL; + if ((anchor->entities = enext) == NULL) { + if (i == 0) + ++i; + else if (i < --src->textSrc.num_anchors) { + memmove(&src->textSrc.anchors[i], + &src->textSrc.anchors[i + 1], + (src->textSrc.num_anchors - i) * + sizeof(XawTextAnchor*)); + XtFree((XtPointer)anchor); + } + if (i >= src->textSrc.num_anchors) { + anchor = NULL; + entity = NULL; + break; + } + anchor = src->textSrc.anchors[i]; + entity = anchor->entities; + continue; + } + } + entity = enext; + } + if (i + 1 < src->textSrc.num_anchors) { + anchor = src->textSrc.anchors[++i]; + entity = anchor->entities; + eprev = NULL; + } + else { + anchor = NULL; + break; + } + eprev = NULL; + } + +exit_anchor_loop: + if (anchor) { + XawTextAnchor *aprev; + + if (anchor->position >= XawMax(right, left + block->length)) + anchor->position += diff; + else if (anchor->position > left && + (aprev = XawTextSourcePrevAnchor(w, anchor))) { + XawTextPosition tmp = anchor->position - aprev->position; + + if (diff) { + while (entity) { + entity->offset += diff; + entity = entity->next; + } + } + entity = anchor->entities; + while (entity) { + entity->offset += tmp; + entity = entity->next; + } + if ((entity = aprev->entities) == NULL) + aprev->entities = anchor->entities; + else { + while (entity->next) + entity = entity->next; + entity->next = anchor->entities; + } + anchor->entities = NULL; + (void)XawTextSourceRemoveAnchor(w, anchor); + --i; + } + else if (diff) { + while (entity) { + entity->offset += diff; + entity = entity->next; + } + } + } + + if (diff) { + /* The first anchor is never removed, and should + * have position 0. + * i should be -1 if attempted to removed the first + * anchor, what can be caused when removing a chunk + * of text of the first entity. + * */ + if (++i == 0) { + anchor = src->textSrc.anchors[0]; + eprev = entity = anchor->entities; + while (entity) { + enext = entity->next; + if (entity->offset + entity->length <= -diff) + XtFree((XtPointer)entity); + else + break; + entity = enext; + } + if (eprev != entity) { + anchor->cache = NULL; + if ((anchor->entities = entity) != NULL) { + if ((entity->offset += diff) < 0) { + entity->length += entity->offset; + entity->offset = 0; + } + } + } + ++i; + } + for (; i < src->textSrc.num_anchors; i++) + src->textSrc.anchors[i]->position += diff; + } + } + + start = left; + end = start + block->length; + while (start < end) { + start = XawTextSourceScan(w, start, XawstEOL, XawsdRight, 1, True); + if (start <= end) { + ++lines; + if (start == XawTextSourceScan(w, 0, XawstAll, XawsdRight, 1, True)) { + lines -= !_XawTextSourceNewLineAtEOF(w); + break; + } + } + } + + info.left = left; + info.right = right; + info.block = block; + XtCallCallbacks(w, XtNpropertyCallback, &info); + + TellSourceChanged(src, left, right, block, lines); + /* Call callbacks, we have changed the buffer */ + XtCallCallbacks(w, XtNcallback, + (XtPointer)((long)src->textSrc.changed)); + } + +#endif /* OLDXAW */ + return (error); +} + +#ifndef OLDXAW +Bool +_XawTextSrcUndo(TextSrcObject src, XawTextPosition *insert_pos) +{ + static wchar_t wnull = 0; + XawTextBlock block; + XawTextUndoList *list, *nlist; + XawTextUndoBuffer *l_state, *r_state; + Boolean changed = src->textSrc.changed; + + if (!src->textSrc.enable_undo || !src->textSrc.undo->num_undo) + return (False); + + list = src->textSrc.undo->pointer; + + if (src->textSrc.undo->dir == XawsdLeft) { + l_state = list->right; + r_state = list->left; + } + else { + l_state = list->left; + r_state = list->right; + } + + if (src->textSrc.undo->l_no_change == l_state + && src->textSrc.undo->r_no_change == r_state) + src->textSrc.changed = False; + else + src->textSrc.changed = True; + + block.firstPos = 0; + block.length = r_state->length; + block.ptr = r_state->buffer ? r_state->buffer : (char*)&wnull; + block.format = r_state->format; + + src->textSrc.undo_state = True; + if (XawTextSourceReplace((Widget)src, l_state->position, l_state->position + + l_state->length, &block) != XawEditDone) { + src->textSrc.undo_state = False; + src->textSrc.changed = changed; + return (False); + } + src->textSrc.undo_state = False; + + ++l_state->refcount; + ++r_state->refcount; + nlist = XtNew(XawTextUndoList); + nlist->left = l_state; + nlist->right = r_state; + nlist->undo = src->textSrc.undo->list; + nlist->redo = NULL; + + if (list == src->textSrc.undo->list) + src->textSrc.undo->end_mark = nlist; + + if (src->textSrc.undo->dir == XawsdLeft) { + if (list->undo == NULL) + src->textSrc.undo->dir = XawsdRight; + else + list = list->undo; + } + else { + if (list->redo == NULL || list->redo == src->textSrc.undo->end_mark) + src->textSrc.undo->dir = XawsdLeft; + else + list = list->redo; + } + *insert_pos = r_state->position + r_state->length; + src->textSrc.undo->pointer = list; + src->textSrc.undo->list->redo = nlist; + src->textSrc.undo->list = nlist; + src->textSrc.undo->merge = src->textSrc.undo->erase = 0; + + if (++src->textSrc.undo->num_list >= UNDO_DEPTH) + UndoGC(src->textSrc.undo); + + return (True); +} + +Bool +_XawTextSrcToggleUndo(TextSrcObject src) +{ + if (!src->textSrc.enable_undo || !src->textSrc.undo->num_undo) + return (False); + + if (src->textSrc.undo->pointer != src->textSrc.undo->list) { + if (src->textSrc.undo->dir == XawsdLeft) { + if (src->textSrc.undo->pointer->redo + && (src->textSrc.undo->pointer->redo + != src->textSrc.undo->end_mark)) { + src->textSrc.undo->pointer = src->textSrc.undo->pointer->redo; + src->textSrc.undo->dir = XawsdRight; + } + } + else { + if (src->textSrc.undo->pointer->undo + && (src->textSrc.undo->pointer != src->textSrc.undo->head)) { + src->textSrc.undo->pointer = src->textSrc.undo->pointer->undo; + src->textSrc.undo->dir = XawsdLeft; + } + } + } + + return (True); +} + +static void +FreeUndoBuffer(XawTextUndo *undo) +{ + unsigned i; + XawTextUndoList *head, *del; + + for (i = 0; i < undo->num_undo; i++) { + if (undo->undo[i]->buffer && undo->undo[i]->buffer != SrcNL && + undo->undo[i]->buffer != (char*)SrcWNL) + XtFree(undo->undo[i]->buffer); + XtFree((char*)undo->undo[i]); + } + XtFree((char*)undo->undo); + head = undo->head; + + del = head; + while (head) { + head = head->redo; + XtFree((char*)del); + del = head; + } + + if (undo->l_save) { + XtFree((char*)undo->l_save); + undo->l_save = NULL; + } + if (undo->r_save) { + XtFree((char*)undo->r_save); + undo->r_save = NULL; + } + if (undo->u_save) { + XtFree((char*)undo->u_save); + undo->u_save = NULL; + } + + undo->list = undo->pointer = undo->head = undo->end_mark = NULL; + undo->l_no_change = undo->r_no_change = NULL; + undo->undo = NULL; + undo->dir = XawsdLeft; + undo->num_undo = undo->num_list = undo->erase = undo->merge = 0; +} + +static void +UndoGC(XawTextUndo *undo) +{ + unsigned i; + XawTextUndoList *head = undo->head, *redo = head->redo; + + if (head == undo->pointer || head == undo->end_mark + || undo->l_no_change == NULL + || head->left == undo->l_no_change || head->right == undo->l_no_change) + return; + + undo->head = redo; + redo->undo = NULL; + + --head->left->refcount; + if (--head->right->refcount == 0) { + for (i = 0; i < undo->num_undo; i+= 2) + if (head->left == undo->undo[i] || head->left == undo->undo[i+1]) { + if (head->left == undo->undo[i+1]) { + XawTextUndoBuffer *tmp = redo->left; + + redo->left = redo->right; + redo->right = tmp; + } + if (head->left->buffer && head->left->buffer != SrcNL && + head->left->buffer != (char*)SrcWNL) + XtFree(head->left->buffer); + XtFree((char*)head->left); + if (head->right->buffer && head->right->buffer != SrcNL && + head->right->buffer != (char*)SrcWNL) + XtFree(head->right->buffer); + XtFree((char*)head->right); + + undo->num_undo -= 2; + memmove(&undo->undo[i], &undo->undo[i + 2], + (undo->num_undo - i) * sizeof(XawTextUndoBuffer*)); + break; + } + } + XtFree((char*)head); + --undo->num_list; +} +#endif /* OLDXAW */ + +/* + * Function: + * XawTextSourceScan + * + * Parameters: + * w - TextSrc Object + * position - position to start scanning + * type - type of thing to scan for + * dir - direction to scan + * count - which occurance if this thing to search for + * include - whether or not to include the character found in + * the position that is returned. + * + * Description: + * Scans the text source for the number and type of item specified. + * + * Returns: + * The position of the text + */ +XawTextPosition +XawTextSourceScan(Widget w, XawTextPosition position, +#if NeedWidePrototypes + int type, int dir, int count, int include +#else + XawTextScanType type, XawTextScanDirection dir, + int count, Boolean include +#endif +) +{ + TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; + + return ((*cclass->textSrc_class.Scan) + (w, position, type, dir, count, include)); +} + +/* + * Function: + * XawTextSourceSearch + * + * Parameters: + * w - TextSource Object + * position - position to start scanning + * dir - direction to scan + * text - the text block to search for. + * + * Returns: + * The position of the text we are searching for or XawTextSearchError. + * + * Description: + * Searchs the text source for the text block passed + */ +XawTextPosition +XawTextSourceSearch(Widget w, XawTextPosition position, +#if NeedWidePrototypes + int dir, +#else + XawTextScanDirection dir, +#endif + XawTextBlock *text) +{ + TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; + + return ((*cclass->textSrc_class.Search)(w, position, dir, text)); +} + +/* + * Function: + * XawTextSourceConvertSelection + * + * Parameters: + * w - TextSrc object + * selection - current selection atom + * target - current target atom + * type - type to conver the selection to + * value - return value that has been converted + * length - "" + * format - format of the returned value + * + * Returns: + * True if the selection has been converted + */ +Boolean +XawTextSourceConvertSelection(Widget w, Atom *selection, Atom *target, + Atom *type, XtPointer *value, + unsigned long *length, int *format) +{ + TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; + + return((*cclass->textSrc_class.ConvertSelection) + (w, selection, target, type, value, length, format)); +} + +/* + * Function: + * XawTextSourceSetSelection + * + * Parameters: + * w - TextSrc object + * left - bounds of the selection + * rigth - "" + * selection - selection atom + * + * Description: + * Allows special setting of the selection. + */ +void +XawTextSourceSetSelection(Widget w, XawTextPosition left, + XawTextPosition right, Atom selection) +{ + TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; + + (*cclass->textSrc_class.SetSelection)(w, left, right, selection); +} + +/* + * External Functions for Multi Text + */ +/* + * TextFormat(): + * returns the format of text: FMT8BIT or FMTWIDE + */ +XrmQuark +_XawTextFormat(TextWidget tw) +{ + return (((TextSrcObject)(tw->text.source))->textSrc.text_format); +} + +/* _XawTextWCToMB(): + * Convert the wchar string to external encoding + * The caller is responsible for freeing both the source and ret string + * + * wstr - source wchar string + * len_in_out - lengh of string. + * As In, length of source wchar string, measured in wchar + * As Out, length of returned string + */ +char * +_XawTextWCToMB(Display *d, wchar_t *wstr, int *len_in_out) +{ + XTextProperty textprop; + + if (XwcTextListToTextProperty(d, (wchar_t**)&wstr, 1, + XTextStyle, &textprop) < Success) { + XtWarningMsg("convertError", "textSource", "XawError", + "Non-character code(s) in buffer.", NULL, NULL); + *len_in_out = 0; + return (NULL); + } + *len_in_out = textprop.nitems; + + return ((char *)textprop.value); +} + +/* _XawTextMBToWC(): + * Convert the string to internal processing codeset WC. + * The caller is responsible for freeing both the source and ret string. + * + * str - source string + * len_in_out - lengh of string + * As In, it is length of source string + * As Out, it is length of returned string, measured in wchar + */ +wchar_t * +_XawTextMBToWC(Display *d, char *str, int *len_in_out) +{ + XTextProperty textprop; + char *buf; + wchar_t **wlist, *wstr; + int count; + + if (*len_in_out == 0) + return (NULL); + + buf = XtMalloc(*len_in_out + 1); + + strncpy(buf, str, *len_in_out); + *(buf + *len_in_out) = '\0'; + if (XmbTextListToTextProperty(d, &buf, 1, XTextStyle, &textprop) != Success) { + XtWarningMsg("convertError", "textSource", "XawError", + "No Memory, or Locale not supported.", NULL, NULL); + XtFree(buf); + *len_in_out = 0; + return (NULL); + } + + XtFree(buf); + if (XwcTextPropertyToTextList(d, &textprop, + (wchar_t***)&wlist, &count) != Success) { + XtWarningMsg("convertError", "multiSourceCreate", "XawError", + "Non-character code(s) in source.", NULL, NULL); + *len_in_out = 0; + return (NULL); + } + wstr = wlist[0]; + *len_in_out = wcslen(wstr); + XtFree((XtPointer)wlist); + + return (wstr); +} + +#ifndef OLDXAW +static int +qcmp_anchors(_Xconst void *left, _Xconst void *right) +{ + return ((*(XawTextAnchor**)left)->position - + (*(XawTextAnchor**)right)->position); +} + +XawTextAnchor * +XawTextSourceAddAnchor(Widget w, XawTextPosition position) +{ + TextSrcObject src = (TextSrcObject)w; + XawTextAnchor *anchor, *panchor; + + if ((panchor = XawTextSourceFindAnchor(w, position)) != NULL) { + XawTextEntity *pentity, *entity; + + if (position - panchor->position < ANCHORS_DIST) + return (panchor); + + if (panchor->cache && panchor->position + panchor->cache->offset + + panchor->cache->length < position) + pentity = entity = panchor->cache; + else + pentity = entity = panchor->entities; + + while (entity && panchor->position + entity->offset + + entity->length < position) { + pentity = entity; + entity = entity->next; + } + if (entity) { + XawTextPosition diff; + + if (panchor->position + entity->offset < position) + position = panchor->position + entity->offset; + + if (position == panchor->position) + return (panchor); + + anchor = XtNew(XawTextAnchor); + diff = position - panchor->position; + + panchor->cache = NULL; + anchor->entities = entity; + if (pentity != entity) + pentity->next = NULL; + else + panchor->entities = NULL; + while (entity) { + entity->offset -= diff; + entity = entity->next; + } + } + else { + anchor = XtNew(XawTextAnchor); + anchor->entities = NULL; + } + } + else { + anchor = XtNew(XawTextAnchor); + anchor->entities = NULL; + } + + anchor->position = position; + anchor->cache = NULL; + + src->textSrc.anchors = (XawTextAnchor**) + XtRealloc((XtPointer)src->textSrc.anchors, sizeof(XawTextAnchor*) * + (src->textSrc.num_anchors + 1)); + src->textSrc.anchors[src->textSrc.num_anchors++] = anchor; + qsort((void*)src->textSrc.anchors, src->textSrc.num_anchors, + sizeof(XawTextAnchor*), qcmp_anchors); + + return (anchor); +} + +XawTextAnchor * +XawTextSourceFindAnchor(Widget w, XawTextPosition position) +{ + TextSrcObject src = (TextSrcObject)w; + int i = 0, left, right, nmemb = src->textSrc.num_anchors; + XawTextAnchor *anchor, **anchors = src->textSrc.anchors; + + left = 0; + right = nmemb - 1; + while (left <= right) { + anchor = anchors[i = (left + right) >> 1]; + if (anchor->position == position) + return (anchor); + else if (position < anchor->position) + right = i - 1; + else + left = i + 1; + } + + if (nmemb) + return (right < 0 ? anchors[0] : anchors[right]); + + return (NULL); +} + +Bool +XawTextSourceAnchorAndEntity(Widget w, XawTextPosition position, + XawTextAnchor **anchor_return, + XawTextEntity **entity_return) +{ + XawTextAnchor *anchor = XawTextSourceFindAnchor(w, position); + XawTextEntity *pentity, *entity; + XawTextPosition offset; + Bool next_anchor = True, retval = False; + + if (anchor->cache && anchor->position + anchor->cache->offset + + anchor->cache->length <= position) + pentity = entity = anchor->cache; + else + pentity = entity = anchor->entities; + while (entity) { + offset = anchor->position + entity->offset; + + if (offset > position) { + retval = next_anchor = False; + break; + } + if (offset + entity->length > position) { + retval = True; + next_anchor = False; + break; + } + pentity = entity; + entity = entity->next; + } + + if (next_anchor) { + *anchor_return = anchor = XawTextSourceNextAnchor(w, anchor); + *entity_return = anchor ? anchor->entities : NULL; + } + else { + *anchor_return = anchor; + *entity_return = retval ? entity : pentity; + } + + if (*anchor_return) + (*anchor_return)->cache = *entity_return; + + return (retval); +} + +XawTextAnchor * +XawTextSourceNextAnchor(Widget w, XawTextAnchor *anchor) +{ + int i; + TextSrcObject src = (TextSrcObject)w; + + for (i = 0; i < src->textSrc.num_anchors - 1; i++) + if (src->textSrc.anchors[i] == anchor) + return (src->textSrc.anchors[i + 1]); + + return (NULL); +} + +XawTextAnchor * +XawTextSourcePrevAnchor(Widget w, XawTextAnchor *anchor) +{ + int i; + TextSrcObject src = (TextSrcObject)w; + + for (i = src->textSrc.num_anchors - 1; i > 0; i--) + if (src->textSrc.anchors[i] == anchor) + return (src->textSrc.anchors[i - 1]); + + return (NULL); +} + +XawTextAnchor * +XawTextSourceRemoveAnchor(Widget w, XawTextAnchor *anchor) +{ + int i; + TextSrcObject src = (TextSrcObject)w; + + for (i = 0; i < src->textSrc.num_anchors; i++) + if (src->textSrc.anchors[i] == anchor) + break; + + if (i == 0) + return (src->textSrc.num_anchors > 1 ? src->textSrc.anchors[1] : NULL); + + if (i < src->textSrc.num_anchors) { + XtFree((XtPointer)anchor); + if (i < --src->textSrc.num_anchors) { + memmove(&src->textSrc.anchors[i], + &src->textSrc.anchors[i + 1], + (src->textSrc.num_anchors - i) * + sizeof(XawTextAnchor*)); + + return (src->textSrc.anchors[i]); + } + } + + return (NULL); +} + +XawTextEntity * +XawTextSourceAddEntity(Widget w, int type, int flags, XtPointer data, + XawTextPosition position, Cardinal length, + XrmQuark property) +{ + XawTextAnchor *next, *anchor = _XawTextSourceFindAnchor(w, position); + XawTextEntity *entity, *eprev; + + /* There is no support for zero length entities for now */ + if (length == 0) + return (NULL); + + if (anchor->cache && anchor->position + anchor->cache->offset + + anchor->cache->length <= position) + eprev = entity = anchor->cache; + else + eprev = entity = anchor->entities; + + while (entity && anchor->position + entity->offset + entity->length <= + position) { + eprev = entity; + entity = entity->next; + } + if (entity && anchor->position + entity->offset < position + length) { + fprintf(stderr, "Cannot (yet) add more than one entity to same region.\n"); + return (NULL); + } + + next = XawTextSourceFindAnchor(w, position + length); + if (next && next != anchor) { + if ((entity = next->entities) != NULL) { + if (next->position + entity->offset < position + length) { + fprintf(stderr, "Cannot (yet) add more than one entity to same region.\n"); + return (NULL); + } + } + if (position + length > next->position) { + XawTextPosition diff = position + length - next->position; + + next->position += diff; + entity = next->entities; + while (entity) { + entity->offset -= diff; + entity = entity->next; + } + entity = anchor->entities; + while (entity && entity->offset < 0) + entity = entity->next; + if (entity && entity->offset < 0) { + if (eprev) + eprev->next = next->entities; + else + anchor->entities = next->entities; + if ((next->entities = entity->next) == NULL) + (void)XawTextSourceRemoveAnchor(w, next); + entity->next = NULL; + + return (XawTextSourceAddEntity(w, type, flags, data, position, + length, property)); + } + } + } + + /* Automatically join sequential entities if possible */ + if (eprev && + anchor->position + eprev->offset + eprev->length == position && + eprev->property == property && eprev->type == type && + eprev->flags == flags && eprev->data == data) { + eprev->length += length; + return (eprev); + } + + entity = XtNew(XawTextEntity); + entity->type = type; + entity->flags = flags; + entity->data = data; + entity->offset = position - anchor->position; + entity->length = length; + entity->property = property; + + if (eprev == NULL) { + anchor->entities = entity; + entity->next = NULL; + anchor->cache = NULL; + } + else if (eprev->offset > entity->offset) { + anchor->cache = NULL; + anchor->entities = entity; + entity->next = eprev; + } + else { + anchor->cache = eprev; + entity->next = eprev->next; + eprev->next = entity; + } + + return (entity); +} + +void +XawTextSourceClearEntities(Widget w, XawTextPosition left, XawTextPosition right) +{ + XawTextAnchor *anchor = XawTextSourceFindAnchor(w, left); + XawTextEntity *entity, *eprev, *enext; + XawTextPosition offset; + int length; + + while (anchor && anchor->entities == NULL) + anchor = XawTextSourceRemoveAnchor(w, anchor); + + if (anchor == NULL || left >= right) + return; + + if (anchor->cache && anchor->position + anchor->cache->offset + + anchor->cache->length < left) + eprev = entity = anchor->cache; + else + eprev = entity = anchor->entities; + + /* find first entity before left position */ + while (anchor->position + entity->offset + entity->length < left) { + eprev = entity; + if ((entity = entity->next) == NULL) { + if ((anchor = XawTextSourceNextAnchor(w, anchor)) == NULL) + return; + if ((eprev = entity = anchor->entities) == NULL) { + fprintf(stderr, "Bad anchor found!\n"); + return; + } + } + } + + offset = anchor->position + entity->offset; + if (offset <= left) { + length = XawMin(entity->length, left - offset); + + if (length <= 0) { + enext = entity->next; + eprev->next = enext; + XtFree((XtPointer)entity); + anchor->cache = NULL; + if (entity == anchor->entities) { + eprev = NULL; + if ((anchor->entities = enext) == NULL) { + if ((anchor = XawTextSourceRemoveAnchor(w, anchor)) == NULL) + return; + entity = anchor->entities; + } + else + entity = enext; + } + else + entity = enext; + } + else { + entity->length = length; + eprev = entity; + entity = entity->next; + } + } + + /* clean everything until right position is reached */ + while (anchor) { + while (entity) { + offset = anchor->position + entity->offset + entity->length; + + if (offset > right) { + anchor->cache = NULL; + entity->offset = XawMax(entity->offset, right - anchor->position); + entity->length = XawMin(entity->length, offset - right); + return; + } + + enext = entity->next; + if (eprev) + eprev->next = enext; + XtFree((XtPointer)entity); + if (entity == anchor->entities) { + eprev = anchor->cache = NULL; + if ((anchor->entities = enext) == NULL) { + if ((anchor = XawTextSourceRemoveAnchor(w, anchor)) == NULL) + return; + entity = anchor->entities; + continue; + } + } + entity = enext; + } + if (anchor) + anchor->cache = NULL; + if ((anchor = XawTextSourceNextAnchor(w, anchor)) != NULL) + entity = anchor->entities; + eprev = NULL; + } +} + +/* checks the anchors up to position, and create an appropriate anchor + * at position, if required. + */ +XawTextAnchor * +_XawTextSourceFindAnchor(Widget w, XawTextPosition position) +{ + XawTextAnchor *anchor; + + anchor = XawTextSourceFindAnchor(w, position); + + position -= position % ANCHORS_DIST; + + if (position - anchor->position >= ANCHORS_DIST) + return (XawTextSourceAddAnchor(w, position)); + + return (anchor); +} +#endif diff --git a/src/TextTr.c b/src/TextTr.c new file mode 100644 index 0000000..f354683 --- /dev/null +++ b/src/TextTr.c @@ -0,0 +1,158 @@ +/* + +Copyright 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* INTERNATIONALIZATION: + +The OMRON R5 contrib added the following action to the old TextTr: + + Ctrlbackslash: reconnect-im() + +This is needed when the im is killed or otherwise becomes unreachable. +This keystroke is evil (inconvenient, hard-to-remember, not obvious) +so I am adding one more translation: + + Kanji: reconnect-im() + +The Japanese user typically hits their Kanji key when they want to do +input. This merely makes sure the input is connected. +*/ + +#include + +char _XawDefaultTextTranslations[] = +"cA:" "beginning-of-line()\n" +"cB:" "backward-character()\n" +"cC:" "insert-selection(CUT_BUFFER0)\n" +"cD:" "delete-next-character()\n" +"cE:" "end-of-line()\n" +"cF:" "forward-character()\n" +#ifndef OLDXAW +"cG:" "keyboard-reset()\n" +#else +"cG:" "multiply(Reset)\n" +#endif +"cH:" "delete-previous-character()\n" +"cJ:" "newline-and-indent()\n" +"cK:" "kill-to-end-of-line()\n" +"cL:" "redraw-display()\n" +"cM:" "newline()\n" +"cN:" "next-line()\n" +"cO:" "newline-and-backup()\n" +"cP:" "previous-line()\n" +"cR:" "search(backward)\n" +"cS:" "search(forward)\n" +"cT:" "transpose-characters()\n" +#ifndef OLDXAW +"cU:" "multiply(Start)\n" +#else +"cU:" "multiply(4)\n" +#endif +"cV:" "next-page()\n" +"cW:" "kill-selection()\n" +"cY:" "insert-selection(SECONDARY)\n" +"cZ:" "scroll-one-line-up()\n" +"mB:" "backward-word()\n" +"mC:" "capitalize-word()\n" +"mF:" "forward-word()\n" +"mI:" "insert-file()\n" +"mK:" "kill-to-end-of-paragraph()\n" +"mL:" "downcase-word()\n" +"mQ:" "form-paragraph()\n" +"mU:" "upcase-word()\n" +"mV:" "previous-page()\n" +#ifndef OLDXAW +"mY:" "kill-ring-yank()\n" +#endif +"mZ:" "scroll-one-line-down()\n" +"~s md:" "kill-word(alnum)\n" +"s md:" "delete-next-word(alnum)\n" +"~s mh:" "backward-kill-word(alnum)\n" +"s mh:" "delete-previous-word(alnum)\n" +":m\\<:" "beginning-of-file()\n" +":m\\>:" "end-of-file()\n" +":m]:" "forward-paragraph()\n" +":m[:" "backward-paragraph()\n" +"~s mDelete:" "backward-kill-word(alnum)\n" +"s mDelete:" "delete-previous-word(alnum)\n" +"~s mBackSpace:" "backward-kill-word(alnum)\n" +"s mBackSpace:" "delete-previous-word(alnum)\n" +"cLeft:" "backward-word(alnum)\n" +"cRight:" "forward-word(alnum)\n" +"cUp:" "backward-paragraph()\n" +"cDown:" "forward-paragraph()\n" +"Home:" "beginning-of-file()\n" +":KP_Home:" "beginning-of-file()\n" +"End:" "end-of-file()\n" +":KP_End:" "end-of-file()\n" +"Next:" "next-page()\n" +":KP_Next:" "next-page()\n" +"Prior:" "previous-page()\n" +":KP_Prior:" "previous-page()\n" +"Right:" "forward-character()\n" +":KP_Right:" "forward-character()\n" +"Left:" "backward-character()\n" +":KP_Left:" "backward-character()\n" +"Down:" "next-line()\n" +":KP_Down:" "next-line()\n" +"Up:" "previous-line()\n" +":KP_Up:" "previous-line()\n" +"Delete:" "delete()\n" +":KP_Delete:" "delete()\n" +"BackSpace:" "delete-previous-character()\n" +"Linefeed:" "newline-and-indent()\n" +"Return:" "newline()\n" +":KP_Enter:" "newline()\n" +"cbackslash:" "reconnect-im()\n" +"Kanji:" "reconnect-im()\n" +#ifndef OLDXAW +":0:" "numeric(0)\n" +":1:" "numeric(1)\n" +":2:" "numeric(2)\n" +":3:" "numeric(3)\n" +":4:" "numeric(4)\n" +":5:" "numeric(5)\n" +":6:" "numeric(6)\n" +":7:" "numeric(7)\n" +":8:" "numeric(8)\n" +":9:" "numeric(9)\n" +":-:" "numeric(-)\n" +":c_:" "undo()\n" +#endif +"s Insert:" "insert-selection(PRIMARY, CUT_BUFFER0)\n" +"Q,:" "insert-char()\n" +":" "insert-char()\n" +":" "enter-window()\n" +":" "leave-window()\n" +":" "focus-in()\n" +":" "focus-out()\n" +":" "select-start()\n" +":" "extend-adjust()\n" +":" "extend-end(PRIMARY, CUT_BUFFER0)\n" +":" "insert-selection(PRIMARY, CUT_BUFFER0)\n" +":" "extend-start()\n" +":" "extend-adjust()\n" +":" "extend-end(PRIMARY, CUT_BUFFER0)\n" +; diff --git a/src/Tip.c b/src/Tip.c new file mode 100644 index 0000000..8328aac --- /dev/null +++ b/src/Tip.c @@ -0,0 +1,637 @@ +/* + * Copyright (c) 1999 by The XFree86 Project, Inc. + * + * 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 XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + * + * Author: Paulo César Pereira de Andrade + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include "Private.h" + +#define TIP_EVENT_MASK (ButtonPressMask | \ + ButtonReleaseMask | \ + PointerMotionMask | \ + ButtonMotionMask | \ + KeyPressMask | \ + KeyReleaseMask | \ + EnterWindowMask | \ + LeaveWindowMask) + +/* + * Types + */ +typedef struct _XawTipInfo { + Screen *screen; + TipWidget tip; + Widget widget; + Bool mapped; + struct _XawTipInfo *next; +} XawTipInfo; + +/* + * Class Methods + */ +static void XawTipClassInitialize(void); +static void XawTipInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawTipDestroy(Widget); +static void XawTipExpose(Widget, XEvent*, Region); +static void XawTipRealize(Widget, Mask*, XSetWindowAttributes*); +static Boolean XawTipSetValues(Widget, Widget, Widget, ArgList, Cardinal*); + +/* + * Prototypes + */ +static void TipEventHandler(Widget, XtPointer, XEvent*, Boolean*); +static void TipShellEventHandler(Widget, XtPointer, XEvent*, Boolean*); +static XawTipInfo *CreateTipInfo(Widget); +static XawTipInfo *FindTipInfo(Widget); +static void ResetTip(XawTipInfo*, Bool); +static void TipTimeoutCallback(XtPointer, XtIntervalId*); +static void TipLayout(XawTipInfo*); +static void TipPosition(XawTipInfo*); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(TipRec, tip.field) +static XtResource resources[] = { + { + XtNforeground, + XtCForeground, + XtRPixel, + sizeof(Pixel), + offset(foreground), + XtRString, + XtDefaultForeground, + }, + { + XtNfont, + XtCFont, + XtRFontStruct, + sizeof(XFontStruct*), + offset(font), + XtRString, + XtDefaultFont + }, + { + XtNfontSet, + XtCFontSet, + XtRFontSet, + sizeof(XFontSet), + offset(fontset), + XtRString, + XtDefaultFontSet + }, + { + XtNtopMargin, + XtCVerticalMargins, + XtRDimension, + sizeof(Dimension), + offset(top_margin), + XtRImmediate, + (XtPointer)2 + }, + { + XtNbottomMargin, + XtCVerticalMargins, + XtRDimension, + sizeof(Dimension), + offset(bottom_margin), + XtRImmediate, + (XtPointer)2 + }, + { + XtNleftMargin, + XtCHorizontalMargins, + XtRDimension, + sizeof(Dimension), + offset(left_margin), + XtRImmediate, + (XtPointer)6 + }, + { + XtNrightMargin, + XtCHorizontalMargins, + XtRDimension, + sizeof(Dimension), + offset(right_margin), + XtRImmediate, + (XtPointer)6 + }, + { + XtNbackingStore, + XtCBackingStore, + XtRBackingStore, + sizeof(int), + offset(backing_store), + XtRImmediate, + (XtPointer)(Always + WhenMapped + NotUseful) + }, + { + XtNtimeout, + XtCTimeout, + XtRInt, + sizeof(int), + offset(timeout), + XtRImmediate, + (XtPointer)500 + }, + { + XawNdisplayList, + XawCDisplayList, + XawRDisplayList, + sizeof(XawDisplayList*), + offset(display_list), + XtRImmediate, + NULL + }, +}; +#undef offset + +TipClassRec tipClassRec = { + /* core */ + { + (WidgetClass)&widgetClassRec, /* superclass */ + "Tip", /* class_name */ + sizeof(TipRec), /* widget_size */ + XawTipClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawTipInitialize, /* initialize */ + NULL, /* initialize_hook */ + XawTipRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawTipDestroy, /* destroy */ + NULL, /* resize */ + XawTipExpose, /* expose */ + XawTipSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* tip */ + { + NULL, /* extension */ + }, +}; + +WidgetClass tipWidgetClass = (WidgetClass)&tipClassRec; + +static XawTipInfo *first_tip; + +/* + * Implementation + */ +static void +XawTipClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore, + NULL, 0); + XtSetTypeConverter(XtRBackingStore, XtRString, XmuCvtBackingStoreToString, + NULL, 0, XtCacheNone, NULL); +} + +/*ARGSUSED*/ +static void +XawTipInitialize(Widget req, Widget w, ArgList args, Cardinal *num_args) +{ + TipWidget tip = (TipWidget)w; + XGCValues values; + + if (!tip->tip.font) XtError("Aborting: no font found\n"); + if (tip->tip.international && !tip->tip.fontset) + XtError("Aborting: no fontset found\n"); + + tip->tip.timer = 0; + + values.foreground = tip->tip.foreground; + values.background = tip->core.background_pixel; + values.font = tip->tip.font->fid; + values.graphics_exposures = False; + + tip->tip.gc = XtAllocateGC(w, 0, GCForeground | GCBackground | GCFont | + GCGraphicsExposures, &values, GCFont, 0); +} + +static void +XawTipDestroy(Widget w) +{ + XawTipInfo *info = FindTipInfo(w); + TipWidget tip = (TipWidget)w; + + if (tip->tip.timer) + XtRemoveTimeOut(tip->tip.timer); + + XtReleaseGC(w, tip->tip.gc); + + XtRemoveEventHandler(XtParent(w), KeyPressMask, False, TipShellEventHandler, + (XtPointer)NULL); + if (info == first_tip) + first_tip = first_tip->next; + else { + XawTipInfo *p = first_tip; + + while (p && p->next != info) + p = p->next; + if (p) + p->next = info->next; + } + XtFree((char*)info); +} + +static void +XawTipRealize(Widget w, Mask *mask, XSetWindowAttributes *attr) +{ + TipWidget tip = (TipWidget)w; + + if (tip->tip.backing_store == Always || + tip->tip.backing_store == NotUseful || + tip->tip.backing_store == WhenMapped) { + *mask |= CWBackingStore; + attr->backing_store = tip->tip.backing_store; + } + else + *mask &= ~CWBackingStore; + *mask |= CWOverrideRedirect; + attr->override_redirect = True; + + XtWindow(w) = XCreateWindow(DisplayOfScreen(XtScreen(w)), + RootWindowOfScreen(XtScreen(w)), + XtX(w), XtY(w), + XtWidth(w) ? XtWidth(w) : 1, + XtHeight(w) ? XtHeight(w) : 1, + XtBorderWidth(w), + DefaultDepthOfScreen(XtScreen(w)), + InputOutput, + (Visual *)CopyFromParent, + *mask, attr); +} + +static void +XawTipExpose(Widget w, XEvent *event, Region region) +{ + TipWidget tip = (TipWidget)w; + GC gc = tip->tip.gc; + char *nl, *label = tip->tip.label; + Position y = tip->tip.top_margin + tip->tip.font->max_bounds.ascent; + int len; + + if (tip->tip.display_list) + XawRunDisplayList(w, tip->tip.display_list, event, region); + + if (tip->tip.international == True) { + Position ksy = tip->tip.top_margin; + XFontSetExtents *ext = XExtentsOfFontSet(tip->tip.fontset); + + ksy += XawAbs(ext->max_ink_extent.y); + + while ((nl = index(label, '\n')) != NULL) { + XmbDrawString(XtDisplay(w), XtWindow(w), tip->tip.fontset, + gc, tip->tip.left_margin, ksy, label, + (int)(nl - label)); + ksy += ext->max_ink_extent.height; + label = nl + 1; + } + len = strlen(label); + if (len) + XmbDrawString(XtDisplay(w), XtWindow(w), tip->tip.fontset, gc, + tip->tip.left_margin, ksy, label, len); + } + else { + while ((nl = index(label, '\n')) != NULL) { + if (tip->tip.encoding) + XDrawString16(XtDisplay(w), XtWindow(w), gc, + tip->tip.left_margin, y, + (XChar2b*)label, (int)(nl - label) >> 1); + else + XDrawString(XtDisplay(w), XtWindow(w), gc, + tip->tip.left_margin, y, label, (int)(nl - label)); + y += tip->tip.font->max_bounds.ascent + + tip->tip.font->max_bounds.descent; + label = nl + 1; + } + len = strlen(label); + if (len) { + if (tip->tip.encoding) + XDrawString16(XtDisplay(w), XtWindow(w), gc, + tip->tip.left_margin, y, (XChar2b*)label, len >> 1); + else + XDrawString(XtDisplay(w), XtWindow(w), gc, + tip->tip.left_margin, y, label, len); + } + } +} + +/*ARGSUSED*/ +static Boolean +XawTipSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + TipWidget curtip = (TipWidget)current; + TipWidget newtip = (TipWidget)cnew; + Boolean redisplay = False; + + if (curtip->tip.font->fid != newtip->tip.font->fid || + curtip->tip.foreground != newtip->tip.foreground) { + XGCValues values; + + values.foreground = newtip->tip.foreground; + values.background = newtip->core.background_pixel; + values.font = newtip->tip.font->fid; + values.graphics_exposures = False; + XtReleaseGC(cnew, curtip->tip.gc); + newtip->tip.gc = XtAllocateGC(cnew, 0, GCForeground | GCBackground | + GCFont | GCGraphicsExposures, &values, + GCFont, 0); + redisplay = True; + } + if (curtip->tip.display_list != newtip->tip.display_list) + redisplay = True; + + return (redisplay); +} + +static void +TipLayout(XawTipInfo *info) +{ + XFontStruct *fs = info->tip->tip.font; + int width = 0, height; + char *nl, *label = info->tip->tip.label; + + if (info->tip->tip.international == True) { + XFontSet fset = info->tip->tip.fontset; + XFontSetExtents *ext = XExtentsOfFontSet(fset); + + height = ext->max_ink_extent.height; + if ((nl = index(label, '\n')) != NULL) { + /*CONSTCOND*/ + while (True) { + int w = XmbTextEscapement(fset, label, (int)(nl - label)); + + if (w > width) + width = w; + if (*nl == '\0') + break; + label = nl + 1; + if (*label) + height += ext->max_ink_extent.height; + if ((nl = index(label, '\n')) == NULL) + nl = index(label, '\0'); + } + } + else + width = XmbTextEscapement(fset, label, strlen(label)); + } + else { + height = fs->max_bounds.ascent + fs->max_bounds.descent; + if ((nl = index(label, '\n')) != NULL) { + /*CONSTCOND*/ + while (True) { + int w = info->tip->tip.encoding ? + XTextWidth16(fs, (XChar2b*)label, (int)(nl - label) >> 1) : + XTextWidth(fs, label, (int)(nl - label)); + if (w > width) + width = w; + if (*nl == '\0') + break; + label = nl + 1; + if (*label) + height += fs->max_bounds.ascent + fs->max_bounds.descent; + if ((nl = index(label, '\n')) == NULL) + nl = index(label, '\0'); + } + } + else + width = info->tip->tip.encoding ? + XTextWidth16(fs, (XChar2b*)label, strlen(label) >> 1) : + XTextWidth(fs, label, strlen(label)); + } + XtWidth(info->tip) = width + info->tip->tip.left_margin + + info->tip->tip.right_margin; + XtHeight(info->tip) = height + info->tip->tip.top_margin + + info->tip->tip.bottom_margin; +} + +#define DEFAULT_TIP_Y_OFFSET 12 +static void +TipPosition(XawTipInfo *info) +{ + Window r, c; + int rx, ry, wx, wy; + unsigned mask; + Position x, y; + + XQueryPointer(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip), + &r, &c, &rx, &ry, &wx, &wy, &mask); + x = rx - (XtWidth(info->tip) >> 1); + y = ry + DEFAULT_TIP_Y_OFFSET; + + if (x >= 0) { + int scr_width = WidthOfScreen(XtScreen(info->tip)); + + if (x + XtWidth(info->tip) + XtBorderWidth(info->tip) > scr_width) + x = scr_width - XtWidth(info->tip) - XtBorderWidth(info->tip); + } + if (x < 0) + x = 0; + if (y >= 0) { + int scr_height = HeightOfScreen(XtScreen(info->tip)); + + if (y + XtHeight(info->tip) + XtBorderWidth(info->tip) > scr_height) + y -= XtHeight(info->tip) + XtBorderWidth(info->tip) + + (DEFAULT_TIP_Y_OFFSET << 1); + } + if (y < 0) + y = 0; + + XMoveResizeWindow(XtDisplay(info->tip), XtWindow(info->tip), + (int)(XtX(info->tip) = x), (int)(XtY(info->tip) = y), + (unsigned)XtWidth(info->tip), (unsigned)XtHeight(info->tip)); +} + +static XawTipInfo * +CreateTipInfo(Widget w) +{ + XawTipInfo *info = XtNew(XawTipInfo); + Widget shell = w; + + info->screen = XtScreen(w); + + while (XtParent(shell)) + shell = XtParent(shell); + + info->tip = (TipWidget)XtCreateWidget("tip", tipWidgetClass, shell, NULL, 0); + XtRealizeWidget((Widget)info->tip); + info->widget = NULL; + info->mapped = False; + info->next = NULL; + XtAddEventHandler(shell, KeyPressMask, False, TipShellEventHandler, + (XtPointer)NULL); + + return (info); +} + +static XawTipInfo * +FindTipInfo(Widget w) +{ + XawTipInfo *ptip, *tip = first_tip; + Screen *screen = XtScreenOfObject(w); + + if (tip == NULL) + return (first_tip = tip = CreateTipInfo(w)); + + for (ptip = tip; tip; ptip = tip, tip = tip->next) + if (tip->screen == screen) + return (tip); + + return (ptip->next = CreateTipInfo(w)); +} + +static void +ResetTip(XawTipInfo *info, Bool add_timeout) +{ + if (info->tip->tip.timer) { + XtRemoveTimeOut(info->tip->tip.timer); + info->tip->tip.timer = 0; + } + if (info->mapped) { + XtRemoveGrab(XtParent((Widget)info->tip)); + XUnmapWindow(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip)); + info->mapped = False; + } + if (add_timeout) { + info->tip->tip.timer = + XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)info->tip), + info->tip->tip.timeout, TipTimeoutCallback, + (XtPointer)info); + } +} + +static void +TipTimeoutCallback(XtPointer closure, XtIntervalId *id) +{ + XawTipInfo *info = (XawTipInfo*)closure; + Arg args[3]; + + info->tip->tip.label = NULL; + info->tip->tip.international = False; + info->tip->tip.encoding = 0; + info->tip->tip.timer = 0; + XtSetArg(args[0], XtNtip, &info->tip->tip.label); + XtSetArg(args[1], XtNinternational, &info->tip->tip.international); + XtSetArg(args[2], XtNencoding, &info->tip->tip.encoding); + XtGetValues(info->widget, args, 3); + + if (info->tip->tip.label) { + TipLayout(info); + TipPosition(info); + XMapRaised(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip)); + XtAddGrab(XtParent((Widget)info->tip), True, True); + info->mapped = True; + } +} + +/*ARGSUSED*/ +static void +TipShellEventHandler(Widget w, XtPointer client_data, XEvent *event, + Boolean *continue_to_dispatch) +{ + ResetTip(FindTipInfo(w), False); +} + +/*ARGSUSED*/ +static void +TipEventHandler(Widget w, XtPointer client_data, XEvent *event, + Boolean *continue_to_dispatch) +{ + XawTipInfo *info = FindTipInfo(w); + Boolean add_timeout; + + if (info->widget != w) { + ResetTip(info, False); + info->widget = w; + } + + switch (event->type) { + case EnterNotify: + add_timeout = True; + break; + case MotionNotify: + /* If any button is pressed, timer is 0 */ + if (info->mapped) + return; + add_timeout = info->tip->tip.timer != 0; + break; + default: + add_timeout = False; + break; + } + ResetTip(info, add_timeout); +} + +/* + * Public routines + */ +void +XawTipEnable(Widget w) +{ + XtAddEventHandler(w, TIP_EVENT_MASK, False, TipEventHandler, + (XtPointer)NULL); +} + +void +XawTipDisable(Widget w) +{ + XawTipInfo *info = FindTipInfo(w); + + XtRemoveEventHandler(w, TIP_EVENT_MASK, False, TipEventHandler, + (XtPointer)NULL); + if (info->widget == w) + ResetTip(info, False); +} diff --git a/src/Toggle.c b/src/Toggle.c new file mode 100644 index 0000000..b484878 --- /dev/null +++ b/src/Toggle.c @@ -0,0 +1,628 @@ +/* + +Copyright 1989, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* + * Author: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + * + * Date: January 12, 1989 + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +/* + * Class Methods + */ +static void XawToggleClassInitialize(void); +static void XawToggleInitialize(Widget, Widget, ArgList, Cardinal*); +static Boolean XawToggleSetValues(Widget, Widget, Widget, ArgList, Cardinal*); + +/* + * Prototypes + */ +static void AddToRadioGroup(RadioGroup*, Widget); +static void CreateRadioGroup(Widget, Widget); +static RadioGroup *GetRadioGroup(Widget); +static void RemoveFromRadioGroup(Widget); +static void TurnOffRadioSiblings(Widget); +static void XawToggleDestroy(Widget, XtPointer, XtPointer); + +/* + * Actions + */ +static void Notify(Widget, XEvent*, String*, Cardinal*); +static void Toggle(Widget, XEvent*, String*, Cardinal*); +static void ToggleSet(Widget, XEvent*, String*, Cardinal*); + +/* + * Initialization + */ +/* + * The order of toggle and notify are important, as the state has + * to be set when we call the notify proc + */ +static char defaultTranslations[] = +":" "highlight(Always)\n" +":" "unhighlight()\n" +",:" "toggle() notify()\n" +; + +#define offset(field) XtOffsetOf(ToggleRec, field) +static XtResource resources[] = { + { + XtNstate, + XtCState, + XtRBoolean, + sizeof(Boolean), + offset(command.set), + XtRString, + "off" + }, + { + XtNradioGroup, + XtCWidget, + XtRWidget, + sizeof(Widget), + offset(toggle.widget), + XtRWidget, + NULL + }, + { + XtNradioData, + XtCRadioData, + XtRPointer, + sizeof(XtPointer), + offset(toggle.radio_data), + XtRPointer, + NULL + }, +}; +#undef offset + +static XtActionsRec actionsList[] = { + {"toggle", Toggle}, + {"notify", Notify}, + {"set", ToggleSet}, +}; + +#define Superclass ((CommandWidgetClass)&commandClassRec) +ToggleClassRec toggleClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "Toggle", /* class_name */ + sizeof(ToggleRec), /* size */ + XawToggleClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawToggleInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + actionsList, /* actions */ + XtNumber(actionsList), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* resource_count */ + NULLQUARK, /* xrm_class */ + False, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + XtInheritResize, /* resize */ + XtInheritExpose, /* expose */ + XawToggleSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + defaultTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* simple */ + { + XtInheritChangeSensitive, /* change_sensitive */ + }, + /* label */ + { + NULL, /* extension */ + }, + /* command */ + { + NULL, /* extension */ + }, + /* toggle */ + { + NULL, /* Set */ + NULL, /* Unset */ + NULL, /* extension */ + } +}; + +WidgetClass toggleWidgetClass = (WidgetClass)&toggleClassRec; + +/* + * Impelementation + */ +static void +XawToggleClassInitialize(void) +{ + XtActionList actions; + Cardinal num_actions; + Cardinal i; + ToggleWidgetClass cclass = (ToggleWidgetClass)toggleWidgetClass; + static XtConvertArgRec parentCvtArgs[] = { + {XtBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.parent), + sizeof(Widget)} + }; + + XawInitializeWidgetSet(); + XtSetTypeConverter(XtRString, XtRWidget, XmuNewCvtStringToWidget, + parentCvtArgs, XtNumber(parentCvtArgs), + XtCacheNone, NULL); + XtSetTypeConverter(XtRWidget, XtRString, XmuCvtWidgetToString, + NULL, 0, XtCacheNone, NULL); + + /* + * Find the set and unset actions in the command widget's action table + */ + XtGetActionList(commandWidgetClass, &actions, &num_actions); + + for (i = 0 ; i < num_actions ; i++) { + if (streq(actions[i].string, "set")) + cclass->toggle_class.Set = actions[i].proc; + if (streq(actions[i].string, "unset")) + cclass->toggle_class.Unset = actions[i].proc; + + if (cclass->toggle_class.Set != NULL && + cclass->toggle_class.Unset != NULL) { + XtFree((char *)actions); + return; + } + } + + /* We should never get here */ + XtError("Aborting, due to errors resolving bindings in the Toggle widget."); +} + +/*ARGSUSED*/ +static void +XawToggleInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + ToggleWidget tw = (ToggleWidget)cnew; + ToggleWidget tw_req = (ToggleWidget)request; + + tw->toggle.radio_group = NULL; + + if (tw->toggle.radio_data == NULL) + tw->toggle.radio_data = (XtPointer)cnew->core.name; + + if (tw->toggle.widget != NULL) { + if (GetRadioGroup(tw->toggle.widget) == NULL) + CreateRadioGroup(cnew, tw->toggle.widget); + else + AddToRadioGroup(GetRadioGroup(tw->toggle.widget), cnew); + } + XtAddCallback(cnew, XtNdestroyCallback, XawToggleDestroy, NULL); + + /* + * Command widget assumes that the widget is unset, so we only + * have to handle the case where it needs to be set + * + * If this widget is in a radio group then it may cause another + * widget to be unset, thus calling the notify proceedure + * + * I want to set the toggle if the user set the state to "On" in + * the resource group, reguardless of what my ancestors did + */ + if (tw_req->command.set) + ToggleSet(cnew, NULL, NULL, NULL); +} + +/*ARGSUSED*/ +static void +ToggleSet(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + ToggleWidgetClass cclass = (ToggleWidgetClass)w->core.widget_class; + + TurnOffRadioSiblings(w); + cclass->toggle_class.Set(w, event, NULL, NULL); +} + +static void +Toggle(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + ToggleWidget tw = (ToggleWidget)w; + ToggleWidgetClass cclass = (ToggleWidgetClass)w->core.widget_class; + + if (tw->command.set) + cclass->toggle_class.Unset(w, event, NULL, NULL); + else + ToggleSet(w, event, params, num_params); +} + +/*ARGSUSED*/ +static void +Notify(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + ToggleWidget tw = (ToggleWidget)w; + long antilint = tw->command.set; + + XtCallCallbacks(w, XtNcallback, (XtPointer)antilint); +} + +/*ARGSUSED*/ +static Boolean +XawToggleSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + ToggleWidget oldtw = (ToggleWidget)current; + ToggleWidget tw = (ToggleWidget)cnew; + ToggleWidget rtw = (ToggleWidget)request; + + if (oldtw->toggle.widget != tw->toggle.widget) + XawToggleChangeRadioGroup(cnew, tw->toggle.widget); + + if (!tw->core.sensitive && oldtw->core.sensitive && rtw->command.set) + tw->command.set = True; + + if (oldtw->command.set != tw->command.set) { + tw->command.set = oldtw->command.set; + Toggle(cnew, NULL, NULL, NULL); + } + + return (False); +} + +/* + * Function: + * XawToggleDestroy + * + * Parameters: + * w - toggle widget that is being destroyed + * temp1 - not used + * temp2 - "" + * + * Description: + * Destroy Callback for toggle widget. + */ +/*ARGSUSED*/ +static void +XawToggleDestroy(Widget w, XtPointer temp1, XtPointer temp2) +{ + RemoveFromRadioGroup(w); +} + +/* + * Function: + * GetRadioGroup + * + * Parameters: + * w - toggle widget who's radio group we are getting + * + * Description: + * Gets the radio group associated with a give toggle widget. + * + * Returns: + * The radio group associated with this toggle group + */ +static RadioGroup * +GetRadioGroup(Widget w) +{ + ToggleWidget tw = (ToggleWidget)w; + + if (tw == NULL) + return (NULL); + + return (tw->toggle.radio_group); +} + +/* + * Function: + * CreateRadioGroup + * + * Parameters: + * w1 - toggle widgets to add to the radio group + * w2 - "" + * + * Description: + * Creates a radio group. give two widgets. + * + * Note: + * A pointer to the group is added to each widget's radio_group field. + */ +static void +CreateRadioGroup(Widget w1, Widget w2) +{ + ToggleWidget tw1 = (ToggleWidget)w1; + ToggleWidget tw2 = (ToggleWidget) w2; + + if (tw1->toggle.radio_group != NULL || tw2->toggle.radio_group != NULL) + XtAppWarning(XtWidgetToApplicationContext(w1), + "Toggle Widget Error - Attempting to create a " + "new toggle group, when one already exists."); + + AddToRadioGroup(NULL, w1); + AddToRadioGroup(GetRadioGroup(w1), w2); +} + +/* + * Function: + * AddToRadioGroup + * + * Parameters: + * group - element of the radio group the we are adding to + * w - new toggle widget to add to the group + * + * Description: + * Adds a toggle to the radio group. + */ +static void +AddToRadioGroup(RadioGroup *group, Widget w) +{ + ToggleWidget tw = (ToggleWidget)w; + RadioGroup *local; + + local = (RadioGroup *)XtMalloc(sizeof(RadioGroup)); + local->widget = w; + tw->toggle.radio_group = local; + + if (group == NULL) { /* Creating new group */ + group = local; + group->next = NULL; + group->prev = NULL; + return; + } + local->prev = group; /* Adding to previous group */ + if ((local->next = group->next) != NULL) + local->next->prev = local; + group->next = local; +} + +/* + * Function: + * TurnOffRadioSiblings + * + * Parameters: + * widget - toggle widget + * + * Description: + * Deactivates all radio siblings. + */ +static void +TurnOffRadioSiblings(Widget w) +{ + RadioGroup *group; + ToggleWidgetClass cclass = (ToggleWidgetClass)w->core.widget_class; + + if ((group = GetRadioGroup(w)) == NULL) /* Punt if there is no group */ + return; + + /* Go to the top of the group */ + for (; group->prev != NULL ; group = group->prev) + ; + + while (group != NULL) { + ToggleWidget local_tog = (ToggleWidget)group->widget; + + if (local_tog->command.set) { + cclass->toggle_class.Unset(group->widget, NULL, NULL, NULL); + Notify(group->widget, NULL, NULL, NULL); + } + group = group->next; + } +} + +/* + * Function: + * RemoveFromRadioGroup + * + * Parameters: + * w - toggle widget to remove + * + * Description: + * Removes a toggle from a RadioGroup. + */ +static void +RemoveFromRadioGroup(Widget w) +{ + RadioGroup *group = GetRadioGroup(w); + if (group != NULL) { + if (group->prev != NULL) + (group->prev)->next = group->next; + if (group->next != NULL) + (group->next)->prev = group->prev; + XtFree((char *)group); + } +} + +/* + * Function: + * XawToggleChangeRadioGroup + * + * Parameters: + * w - toggle widget to change groups + * radio_group - any widget in the new group + * + * Description: + * Allows a toggle widget to change radio groups. + */ +void +XawToggleChangeRadioGroup(Widget w, Widget radio_group) +{ + ToggleWidget tw = (ToggleWidget)w; + RadioGroup *group; + + RemoveFromRadioGroup(w); + + /* + * If the toggle that we are about to add is set then we will + * unset all toggles in the new radio group + */ + + if (tw->command.set && radio_group != NULL) + XawToggleUnsetCurrent(radio_group); + + if (radio_group != NULL) { + if ((group = GetRadioGroup(radio_group)) == NULL) + CreateRadioGroup(w, radio_group); + else + AddToRadioGroup(group, w); + } +} + +/* + * Function: + * XawToggleGetCurrent + * + * Parameters: + * w - any toggle widget in the toggle group + * + * Description: + * Returns the RadioData associated with the toggle + * widget that is currently active in a toggle group. + * + * Returns: + * The XtNradioData associated with the toggle widget + */ +XtPointer +XawToggleGetCurrent(Widget w) +{ + RadioGroup *group; + + if ((group = GetRadioGroup(w)) == NULL) + return (NULL); + + for (; group->prev != NULL ; group = group->prev) + ; + + while (group != NULL) { + ToggleWidget local_tog = (ToggleWidget)group->widget; + + if (local_tog->command.set) + return (local_tog->toggle.radio_data); + group = group->next; + } + + return (NULL); +} + +/* + * Function: + * XawToggleSetCurrent + * + * Parameters: + * radio_group - any toggle widget in the toggle group + * radio_data - radio data of the toggle widget to set + * + * Description: + * Sets the Toggle widget associated with the radio_data specified. + */ +void +XawToggleSetCurrent(Widget radio_group, XtPointer radio_data) +{ + RadioGroup *group; + ToggleWidget local_tog; + + /* Special case of no radio group */ + + if ((group = GetRadioGroup(radio_group)) == NULL) { + local_tog = (ToggleWidget)radio_group; + + if (local_tog->toggle.radio_data == radio_data && + !local_tog->command.set) { + ToggleSet(radio_group, NULL, NULL, NULL); + Notify(radio_group, NULL, NULL, NULL); + } + return; + } + + /* + * find top of radio_roup + */ + for (; group->prev != NULL ; group = group->prev) + ; + + /* + * search for matching radio data + */ + while (group != NULL) { + local_tog = (ToggleWidget)group->widget; + + if (local_tog->toggle.radio_data == radio_data) { + if (!local_tog->command.set) { /* if not already set */ + ToggleSet(group->widget, NULL, NULL, NULL); + Notify(group->widget, NULL, NULL, NULL); + } + return; /* found it, done */ + } + group = group->next; + } +} + +/* + * Function: + * XawToggleUnsetCurrent + * + * Parameters: + * radio_group - any toggle widget in the toggle group + * + * Description: + * Unsets all Toggles in the radio_group specified. + */ +void +XawToggleUnsetCurrent(Widget radio_group) +{ + ToggleWidgetClass cclass; + ToggleWidget local_tog = (ToggleWidget)radio_group; + + /* Special Case no radio group */ + + if (local_tog->command.set) { + cclass = (ToggleWidgetClass)local_tog->core.widget_class; + cclass->toggle_class.Unset(radio_group, NULL, NULL, NULL); + Notify(radio_group, NULL, NULL, NULL); + } + if (GetRadioGroup(radio_group) == NULL) + return; + + TurnOffRadioSiblings(radio_group); +} diff --git a/src/Tree.c b/src/Tree.c new file mode 100644 index 0000000..f4781bf --- /dev/null +++ b/src/Tree.c @@ -0,0 +1,1014 @@ +/* + +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1989 Prentice Hall + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation. + * + * Prentice Hall and the authors disclaim all warranties with regard + * to this software, including all implied warranties of merchantability and + * fitness. In no event shall Prentice Hall or the authors be liable + * for any special, indirect or cosequential damages or any damages whatsoever + * resulting from loss of use, data or profits, whether in an action of + * contract, negligence or other tortious action, arising out of or in + * connection with the use or performance of this software. + * + * Authors: Jim Fulton, MIT X Consortium, + * based on a version by Douglas Young, Prentice Hall + * + * This widget is based on the Tree widget described on pages 397-419 of + * Douglas Young's book "The X Window System, Programming and Applications + * with Xt OSF/Motif Edition." The layout code has been rewritten to use + * additional blank space to make the structure of the graph easier to see + * as well as to support vertical trees. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include "Private.h" + +#define IsHorizontal(tw) ((tw)->tree.gravity == WestGravity || \ + (tw)->tree.gravity == EastGravity) + +/* + * Class Methods + */ +static void XawTreeChangeManaged(Widget); +static void XawTreeClassInitialize(void); +static void XawTreeConstraintDestroy(Widget); +static void XawTreeConstraintInitialize(Widget, Widget, ArgList, Cardinal*); +static Boolean XawTreeConstraintSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static void XawTreeDestroy(Widget); +static XtGeometryResult XawTreeGeometryManager(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawTreeInitialize(Widget, Widget, ArgList, Cardinal*); +static XtGeometryResult XawTreeQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawTreeRedisplay(Widget, XEvent*, Region); +static Boolean XawTreeSetValues(Widget, Widget, Widget, ArgList, Cardinal*); + +/* + * Prototypes + */ +static void arrange_subtree(TreeWidget, Widget, int, int, int); +static void check_gravity(TreeWidget, XtGravity); +static void compute_bounding_box_subtree(TreeWidget, Widget, int); +static void delete_node(Widget, Widget); +static GC get_tree_gc(TreeWidget); +static void initialize_dimensions(Dimension**, int*, int); +static void insert_node(Widget, Widget); +static void layout_tree(TreeWidget, Bool); +static void set_positions(TreeWidget, Widget, int); +static void set_tree_size(TreeWidget, Bool, unsigned int, unsigned int); + +/* + * Initialization + */ + +/* + * resources of the tree itself + */ +static XtResource resources[] = { + { XtNautoReconfigure, XtCAutoReconfigure, XtRBoolean, sizeof (Boolean), + XtOffsetOf(TreeRec, tree.auto_reconfigure), XtRImmediate, + (XtPointer) FALSE }, + { XtNhSpace, XtCHSpace, XtRDimension, sizeof (Dimension), + XtOffsetOf(TreeRec, tree.hpad), XtRImmediate, (XtPointer) 0 }, + { XtNvSpace, XtCVSpace, XtRDimension, sizeof (Dimension), + XtOffsetOf(TreeRec, tree.vpad), XtRImmediate, (XtPointer) 0 }, + { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel), + XtOffsetOf(TreeRec, tree.foreground), XtRString, + XtDefaultForeground}, + { XtNlineWidth, XtCLineWidth, XtRDimension, sizeof (Dimension), + XtOffsetOf(TreeRec, tree.line_width), XtRImmediate, (XtPointer) 0 }, + { XtNgravity, XtCGravity, XtRGravity, sizeof (XtGravity), + XtOffsetOf(TreeRec, tree.gravity), XtRImmediate, + (XtPointer) WestGravity }, +#ifndef OLDXAW + { XawNdisplayList, XawCDisplayList, XawRDisplayList, sizeof(XawDisplayList*), + XtOffsetOf(TreeRec, tree.display_list), XtRImmediate, + NULL }, +#endif +}; + + +/* + * resources that are attached to all children of the tree + */ +static XtResource treeConstraintResources[] = { + { XtNtreeParent, XtCTreeParent, XtRWidget, sizeof (Widget), + XtOffsetOf(TreeConstraintsRec, tree.parent), XtRImmediate, NULL }, + { XtNtreeGC, XtCTreeGC, XtRGC, sizeof(GC), + XtOffsetOf(TreeConstraintsRec, tree.gc), XtRImmediate, NULL }, +}; + + +TreeClassRec treeClassRec = { + { + /* core_class fields */ + (WidgetClass) &constraintClassRec, /* superclass */ + "Tree", /* class_name */ + sizeof(TreeRec), /* widget_size */ + XawTreeClassInitialize, /* class_init */ + NULL, /* class_part_init */ + FALSE, /* class_inited */ + XawTreeInitialize, /* initialize */ + NULL, /* initialize_hook */ + XtInheritRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + TRUE, /* compress_motion */ + TRUE, /* compress_exposure */ + TRUE, /* compress_enterleave*/ + TRUE, /* visible_interest */ + XawTreeDestroy, /* destroy */ + NULL, /* resize */ + XawTreeRedisplay, /* expose */ + XawTreeSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XawTreeQueryGeometry, /* query_geometry */ + NULL, /* display_accelerator*/ + NULL, /* extension */ + }, + { + /* composite_class fields */ + XawTreeGeometryManager, /* geometry_manager */ + XawTreeChangeManaged, /* change_managed */ + XtInheritInsertChild, /* insert_child */ + XtInheritDeleteChild, /* delete_child */ + NULL, /* extension */ + }, + { + /* constraint_class fields */ + treeConstraintResources, /* subresources */ + XtNumber(treeConstraintResources), /* subresource_count */ + sizeof(TreeConstraintsRec), /* constraint_size */ + XawTreeConstraintInitialize, /* initialize */ + XawTreeConstraintDestroy, /* destroy */ + XawTreeConstraintSetValues, /* set_values */ + NULL, /* extension */ + }, + { + /* Tree class fields */ + NULL, /* ignore */ + } +}; + +WidgetClass treeWidgetClass = (WidgetClass) &treeClassRec; + + +/***************************************************************************** + * * + * tree utility routines * + * * + *****************************************************************************/ + +static void +initialize_dimensions(Dimension **listp, int *sizep, int n) +{ + int i; + Dimension *l; + + if (!*listp) { + *listp = (Dimension *) XtCalloc ((unsigned int) n, + (unsigned int) sizeof(Dimension)); + *sizep = ((*listp) ? n : 0); + return; + } + if (n > *sizep) { + *listp = (Dimension *) XtRealloc((char *) *listp, + (unsigned int) (n*sizeof(Dimension))); + if (!*listp) { + *sizep = 0; + return; + } + for (i = *sizep, l = (*listp) + i; i < n; i++, l++) *l = 0; + *sizep = n; + } + return; +} + +static GC +get_tree_gc(TreeWidget w) +{ + XtGCMask valuemask = GCBackground | GCForeground; + XGCValues values; + + values.background = w->core.background_pixel; + values.foreground = w->tree.foreground; + if (w->tree.line_width != 0) { + valuemask |= GCLineWidth; + values.line_width = w->tree.line_width; + } + + return XtGetGC ((Widget) w, valuemask, &values); +} + +static void +insert_node(Widget parent, Widget node) +{ + TreeConstraints pc; + TreeConstraints nc = TREE_CONSTRAINT(node); + int nindex; + + nc->tree.parent = parent; + + if (parent == NULL) return; + + /* + * If there isn't more room in the children array, + * allocate additional space. + */ + pc = TREE_CONSTRAINT(parent); + nindex = pc->tree.n_children; + + if (pc->tree.n_children == pc->tree.max_children) { + pc->tree.max_children += (pc->tree.max_children / 2) + 2; + pc->tree.children = (WidgetList) XtRealloc ((char *)pc->tree.children, + (unsigned int) + ((pc->tree.max_children) * + sizeof(Widget))); + } + + /* + * Add the sub_node in the next available slot and + * increment the counter. + */ + pc->tree.children[nindex] = node; + pc->tree.n_children++; +} + +static void +delete_node(Widget parent, Widget node) +{ + TreeConstraints pc; + int pos, i; + + /* + * Make sure the parent exists. + */ + if (!parent) return; + + pc = TREE_CONSTRAINT(parent); + + /* + * Find the sub_node on its parent's list. + */ + for (pos = 0; pos < pc->tree.n_children; pos++) + if (pc->tree.children[pos] == node) break; + + if (pos == pc->tree.n_children) return; + + /* + * Decrement the number of children + */ + pc->tree.n_children--; + + /* + * Fill in the gap left by the sub_node. + * Zero the last slot for good luck. + */ + for (i = pos; i < pc->tree.n_children; i++) + pc->tree.children[i] = pc->tree.children[i+1]; + + pc->tree.children[pc->tree.n_children] = NULL; +} + +static void +check_gravity(TreeWidget tw, XtGravity grav) +{ + switch (tw->tree.gravity) { + case WestGravity: case NorthGravity: case EastGravity: case SouthGravity: + break; + default: + tw->tree.gravity = grav; + break; + } +} + + +/***************************************************************************** + * * + * tree class methods * + * * + *****************************************************************************/ + +static void +XawTreeClassInitialize(void) +{ + XawInitializeWidgetSet(); + XtAddConverter(XtRString, XtRGravity, XmuCvtStringToGravity, NULL, 0); + XtSetTypeConverter(XtRGravity, XtRString, XmuCvtGravityToString, + NULL, 0, XtCacheNone, NULL); +} + + +/*ARGSUSED*/ +static void +XawTreeInitialize(Widget grequest, Widget gnew, + ArgList args, Cardinal *num_args) +{ + TreeWidget request = (TreeWidget) grequest, cnew = (TreeWidget) gnew; + Arg arglist[2]; + + /* + * Make sure the widget's width and height are + * greater than zero. + */ + if (request->core.width <= 0) cnew->core.width = 5; + if (request->core.height <= 0) cnew->core.height = 5; + + /* + * Set the padding according to the orientation + */ + if (request->tree.hpad == 0 && request->tree.vpad == 0) { + if (IsHorizontal (request)) { + cnew->tree.hpad = TREE_HORIZONTAL_DEFAULT_SPACING; + cnew->tree.vpad = TREE_VERTICAL_DEFAULT_SPACING; + } else { + cnew->tree.hpad = TREE_VERTICAL_DEFAULT_SPACING; + cnew->tree.vpad = TREE_HORIZONTAL_DEFAULT_SPACING; + } + } + + /* + * Create a graphics context for the connecting lines. + */ + cnew->tree.gc = get_tree_gc (cnew); + + /* + * Create the hidden root widget. + */ + cnew->tree.tree_root = (Widget) NULL; + XtSetArg(arglist[0], XtNwidth, 1); + XtSetArg(arglist[1], XtNheight, 1); + cnew->tree.tree_root = XtCreateWidget ("root", widgetClass, gnew, + arglist,TWO); + + /* + * Allocate the array used to hold the widest values per depth + */ + cnew->tree.largest = NULL; + cnew->tree.n_largest = 0; + initialize_dimensions (&cnew->tree.largest, &cnew->tree.n_largest, + TREE_INITIAL_DEPTH); + + /* + * make sure that our gravity is one of the acceptable values + */ + check_gravity (cnew, WestGravity); +} + + +/* ARGSUSED */ +static void +XawTreeConstraintInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + TreeConstraints tc = TREE_CONSTRAINT(cnew); + TreeWidget tw = (TreeWidget) cnew->core.parent; + + /* + * Initialize the widget to have no sub-nodes. + */ + tc->tree.n_children = 0; + tc->tree.max_children = 0; + tc->tree.children = (Widget *) NULL; + tc->tree.x = tc->tree.y = 0; + tc->tree.bbsubwidth = 0; + tc->tree.bbsubheight = 0; + + + /* + * If this widget has a super-node, add it to that + * widget' sub-nodes list. Otherwise make it a sub-node of + * the tree_root widget. + */ + if (tc->tree.parent) + insert_node (tc->tree.parent, cnew); + else if (tw->tree.tree_root) + insert_node (tw->tree.tree_root, cnew); +} + + +/* ARGSUSED */ +static Boolean +XawTreeSetValues(Widget gcurrent, Widget grequest, Widget gnew, + ArgList args, Cardinal *num_args) +{ + TreeWidget current = (TreeWidget) gcurrent, cnew = (TreeWidget) gnew; + Boolean redraw = FALSE; + + /* + * If the foreground color has changed, redo the GC's + * and indicate a redraw. + */ + if (cnew->tree.foreground != current->tree.foreground || + cnew->core.background_pixel != current->core.background_pixel || + cnew->tree.line_width != current->tree.line_width) { + XtReleaseGC (gnew, cnew->tree.gc); + cnew->tree.gc = get_tree_gc (cnew); + redraw = TRUE; + } + + /* + * If the minimum spacing has changed, recalculate the + * tree layout. layout_tree() does a redraw, so we don't + * need SetValues to do another one. + */ + if (cnew->tree.gravity != current->tree.gravity) { + check_gravity (cnew, current->tree.gravity); + } + + if (IsHorizontal(cnew) != IsHorizontal(current)) { + if (cnew->tree.vpad == current->tree.vpad && + cnew->tree.hpad == current->tree.hpad) { + cnew->tree.vpad = current->tree.hpad; + cnew->tree.hpad = current->tree.vpad; + } + } + + if (cnew->tree.vpad != current->tree.vpad || + cnew->tree.hpad != current->tree.hpad || + cnew->tree.gravity != current->tree.gravity) { + layout_tree (cnew, TRUE); + redraw = FALSE; + } + return redraw; +} + + +/* ARGSUSED */ +static Boolean +XawTreeConstraintSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + TreeConstraints newc = TREE_CONSTRAINT(cnew); + TreeConstraints curc = TREE_CONSTRAINT(current); + TreeWidget tw = (TreeWidget) cnew->core.parent; + + /* + * If the parent field has changed, remove the widget + * from the old widget's children list and add it to the + * new one. + */ + if (curc->tree.parent != newc->tree.parent){ + if (curc->tree.parent) + delete_node (curc->tree.parent, cnew); + if (newc->tree.parent) + insert_node(newc->tree.parent, cnew); + + /* + * If the Tree widget has been realized, + * compute new layout. + */ + if (XtIsRealized((Widget)tw)) + layout_tree (tw, FALSE); + } + return False; +} + + +static void +XawTreeConstraintDestroy(Widget w) +{ + TreeConstraints tc = TREE_CONSTRAINT(w); + TreeWidget tw = (TreeWidget) XtParent(w); + int i; + + /* + * Remove the widget from its parent's sub-nodes list and + * make all this widget's sub-nodes sub-nodes of the parent. + */ + + if (tw->tree.tree_root == w) { + if (tc->tree.n_children > 0) + tw->tree.tree_root = tc->tree.children[0]; + else + tw->tree.tree_root = NULL; + } + + delete_node (tc->tree.parent, (Widget) w); + for (i = 0; i< tc->tree.n_children; i++) + insert_node (tc->tree.parent, tc->tree.children[i]); + + layout_tree ((TreeWidget) (w->core.parent), FALSE); +} + +/* ARGSUSED */ +static XtGeometryResult +XawTreeGeometryManager(Widget w, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + + TreeWidget tw = (TreeWidget) w->core.parent; + + /* + * No position changes allowed!. + */ + if ((request->request_mode & CWX && request->x!=w->core.x) + ||(request->request_mode & CWY && request->y!=w->core.y)) + return (XtGeometryNo); + + /* + * Allow all resize requests. + */ + + if (request->request_mode & CWWidth) + w->core.width = request->width; + if (request->request_mode & CWHeight) + w->core.height = request->height; + if (request->request_mode & CWBorderWidth) + w->core.border_width = request->border_width; + + if (tw->tree.auto_reconfigure) layout_tree (tw, FALSE); + return (XtGeometryYes); +} + +static void +XawTreeChangeManaged(Widget gw) +{ + layout_tree ((TreeWidget) gw, FALSE); +} + + +static void +XawTreeDestroy(Widget gw) +{ + TreeWidget w = (TreeWidget) gw; + + XtReleaseGC (gw, w->tree.gc); + if (w->tree.largest) XtFree ((char *) w->tree.largest); +} + + +/* ARGSUSED */ +static void +XawTreeRedisplay(Widget gw, XEvent *event, Region region) +{ + TreeWidget tw = (TreeWidget) gw; + +#ifndef OLDXAW + if (tw->tree.display_list) + XawRunDisplayList(gw, tw->tree.display_list, event, region); +#endif + + /* + * If the Tree widget is visible, visit each managed child. + */ + if (tw->core.visible) { + Cardinal i; + int j; + Display *dpy = XtDisplay (tw); + Window w = XtWindow (tw); + + for (i = 0; i < tw->composite.num_children; i++) { + Widget child = tw->composite.children[i]; + TreeConstraints tc = TREE_CONSTRAINT(child); + + /* + * Don't draw lines from the fake tree_root. + */ + if (child != tw->tree.tree_root && tc->tree.n_children) { + int srcx = child->core.x + child->core.border_width; + int srcy = child->core.y + child->core.border_width; + + switch (tw->tree.gravity) { + case WestGravity: + srcx += child->core.width + child->core.border_width; + /* fall through */ + case EastGravity: + srcy += child->core.height / 2; + break; + + case NorthGravity: + srcy += child->core.height + child->core.border_width; + /* fall through */ + case SouthGravity: + srcx += child->core.width / 2; + break; + } + + for (j = 0; j < tc->tree.n_children; j++) { + Widget k = tc->tree.children[j]; + GC gc = (tc->tree.gc ? tc->tree.gc : tw->tree.gc); + + switch (tw->tree.gravity) { + case WestGravity: + /* + * right center to left center + */ + XDrawLine (dpy, w, gc, srcx, srcy, + (int) k->core.x, + (k->core.y + ((int) k->core.border_width) + + ((int) k->core.height) / 2)); + break; + + case NorthGravity: + /* + * bottom center to top center + */ + XDrawLine (dpy, w, gc, srcx, srcy, + (k->core.x + ((int) k->core.border_width) + + ((int) k->core.width) / 2), + (int) k->core.y); + break; + + case EastGravity: + /* + * left center to right center + */ + XDrawLine (dpy, w, gc, srcx, srcy, + (k->core.x + + (((int) k->core.border_width) << 1) + + (int) k->core.width), + (k->core.y + ((int) k->core.border_width) + + ((int) k->core.height) / 2)); + break; + + case SouthGravity: + /* + * top center to bottom center + */ + XDrawLine (dpy, w, gc, srcx, srcy, + (k->core.x + ((int) k->core.border_width) + + ((int) k->core.width) / 2), + (k->core.y + + (((int) k->core.border_width) << 1) + + (int) k->core.height)); + break; + } + } + } + } + } +} + +static XtGeometryResult +XawTreeQueryGeometry(Widget w, XtWidgetGeometry *intended, + XtWidgetGeometry *preferred) +{ + TreeWidget tw = (TreeWidget) w; + + preferred->request_mode = (CWWidth | CWHeight); + preferred->width = tw->tree.maxwidth; + preferred->height = tw->tree.maxheight; + + if (((intended->request_mode & (CWWidth | CWHeight)) == + (CWWidth | CWHeight)) && + intended->width == preferred->width && + intended->height == preferred->height) + return XtGeometryYes; + else if (preferred->width == w->core.width && + preferred->height == w->core.height) + return XtGeometryNo; + else + return XtGeometryAlmost; +} + + +/***************************************************************************** + * * + * tree layout algorithm * + * * + * Each node in the tree is "shrink-wrapped" with a minimal bounding * + * rectangle, laid next to its siblings (with a small about of padding in * + * between) and then wrapped with their parent. Parents are centered about * + * their children (or vice versa if the parent is larger than the children). * + * * + *****************************************************************************/ + +static void +compute_bounding_box_subtree(TreeWidget tree, Widget w, int depth) +{ + TreeConstraints tc = TREE_CONSTRAINT(w); /* info attached to all kids */ + int i; + Bool horiz = IsHorizontal (tree); + Dimension newwidth, newheight; + Dimension bw2 = w->core.border_width * 2; + + /* + * Set the max-size per level. + */ + if (depth >= tree->tree.n_largest) { + initialize_dimensions (&tree->tree.largest, + &tree->tree.n_largest, depth + 1); + } + newwidth = ((horiz ? w->core.width : w->core.height) + bw2); + if (tree->tree.largest[depth] < newwidth) + tree->tree.largest[depth] = newwidth; + + + /* + * initialize + */ + tc->tree.bbwidth = w->core.width + bw2; + tc->tree.bbheight = w->core.height + bw2; + + if (tc->tree.n_children == 0) return; + + /* + * Figure the size of the opposite dimension (vertical if tree is + * horizontal, else vice versa). The other dimension will be set + * in the second pass once we know the maximum dimensions. + */ + newwidth = 0; + newheight = 0; + for (i = 0; i < tc->tree.n_children; i++) { + Widget child = tc->tree.children[i]; + TreeConstraints cc = TREE_CONSTRAINT(child); + + compute_bounding_box_subtree (tree, child, depth + 1); + + if (horiz) { + if (newwidth < cc->tree.bbwidth) newwidth = cc->tree.bbwidth; + newheight += tree->tree.vpad + cc->tree.bbheight; + } else { + if (newheight < cc->tree.bbheight) newheight = cc->tree.bbheight; + newwidth += tree->tree.hpad + cc->tree.bbwidth; + } + } + + + tc->tree.bbsubwidth = newwidth; + tc->tree.bbsubheight = newheight; + + /* + * Now fit parent onto side (or top) of bounding box and correct for + * extra padding. Be careful of unsigned arithmetic. + */ + if (horiz) { + tc->tree.bbwidth += tree->tree.hpad + newwidth; + newheight -= tree->tree.vpad; + if (newheight > tc->tree.bbheight) tc->tree.bbheight = newheight; + } else { + tc->tree.bbheight += tree->tree.vpad + newheight; + newwidth -= tree->tree.hpad; + if (newwidth > tc->tree.bbwidth) tc->tree.bbwidth = newwidth; + } +} + + +static void +set_positions(TreeWidget tw, Widget w, int level) +{ + int i; + + if (w) { + TreeConstraints tc = TREE_CONSTRAINT(w); + + if (level > 0) { + /* + * mirror if necessary + */ + switch (tw->tree.gravity) { + case EastGravity: + tc->tree.x = (((Position) tw->tree.maxwidth) - + ((Position) w->core.width) - tc->tree.x); + break; + + case SouthGravity: + tc->tree.y = (((Position) tw->tree.maxheight) - + ((Position) w->core.height) - tc->tree.y); + break; + } + + /* + * Move the widget into position. + */ + XtMoveWidget (w, tc->tree.x, tc->tree.y); + } + + /* + * Set the positions of all children. + */ + for (i = 0; i < tc->tree.n_children; i++) + set_positions (tw, tc->tree.children[i], level + 1); + } +} + + +static void +arrange_subtree(TreeWidget tree, Widget w, int depth, int x, int y) +{ + TreeConstraints tc = TREE_CONSTRAINT(w); /* info attached to all kids */ + TreeConstraints firstcc, lastcc; + int i; + int newx, newy; + Bool horiz = IsHorizontal (tree); + Widget child = NULL; + Dimension tmp; + Dimension bw2 = w->core.border_width * 2; + Bool relayout = True; + + + /* + * If no children, then just lay out where requested. + */ + tc->tree.x = x; + tc->tree.y = y; + + if (horiz) { + int myh = (w->core.height + bw2); + + if (myh > (int)tc->tree.bbsubheight) { + y += (myh - (int)tc->tree.bbsubheight) / 2; + relayout = False; + } + } else { + int myw = (w->core.width + bw2); + + if (myw > (int)tc->tree.bbsubwidth) { + x += (myw - (int)tc->tree.bbsubwidth) / 2; + relayout = False; + } + } + + if ((tmp = ((Dimension) x) + tc->tree.bbwidth) > tree->tree.maxwidth) + tree->tree.maxwidth = tmp; + if ((tmp = ((Dimension) y) + tc->tree.bbheight) > tree->tree.maxheight) + tree->tree.maxheight = tmp; + + if (tc->tree.n_children == 0) return; + + + /* + * Have children, so walk down tree laying out children, then laying + * out parents. + */ + if (horiz) { + newx = x + tree->tree.largest[depth]; + if (depth > 0) newx += tree->tree.hpad; + newy = y; + } else { + newx = x; + newy = y + tree->tree.largest[depth]; + if (depth > 0) newy += tree->tree.vpad; + } + + for (i = 0; i < tc->tree.n_children; i++) { + TreeConstraints cc; + + child = tc->tree.children[i]; /* last value is used outside loop */ + cc = TREE_CONSTRAINT(child); + + arrange_subtree (tree, child, depth + 1, newx, newy); + if (horiz) { + newy += tree->tree.vpad + cc->tree.bbheight; + } else { + newx += tree->tree.hpad + cc->tree.bbwidth; + } + } + + /* + * now layout parent between first and last children + */ + if (relayout) { + Position adjusted; + firstcc = TREE_CONSTRAINT (tc->tree.children[0]); + lastcc = TREE_CONSTRAINT (child); + + /* Adjustments are disallowed if they result in a position above + * or to the left of the originally requested position, because + * this could collide with the position of the previous sibling. + */ + if (horiz) { + tc->tree.x = x; + adjusted = firstcc->tree.y + + ((lastcc->tree.y + (Position) child->core.height + + (Position) child->core.border_width * 2 - + firstcc->tree.y - (Position) w->core.height - + (Position) w->core.border_width * 2 + 1) / 2); + if (adjusted > tc->tree.y) tc->tree.y = adjusted; + } else { + adjusted = firstcc->tree.x + + ((lastcc->tree.x + (Position) child->core.width + + (Position) child->core.border_width * 2 - + firstcc->tree.x - (Position) w->core.width - + (Position) w->core.border_width * 2 + 1) / 2); + if (adjusted > tc->tree.x) tc->tree.x = adjusted; + tc->tree.y = y; + } + } +} + +static void +set_tree_size(TreeWidget tw, Bool insetvalues, + unsigned int width, unsigned int height) +{ + if (insetvalues) { + tw->core.width = width; + tw->core.height = height; + } else { + Dimension replyWidth = 0, replyHeight = 0; + XtGeometryResult result = XtMakeResizeRequest ((Widget) tw, + width, height, + &replyWidth, + &replyHeight); + /* + * Accept any compromise. + */ + if (result == XtGeometryAlmost) + XtMakeResizeRequest ((Widget) tw, replyWidth, replyHeight, + (Dimension *) NULL, (Dimension *) NULL); + } + return; +} + +static void +layout_tree(TreeWidget tw, Bool insetvalues) +{ + int i; + Dimension *dp; + + /* + * Do a depth-first search computing the width and height of the bounding + * box for the tree at that position (and below). Then, walk again using + * this information to layout the children at each level. + */ + + if (tw->tree.tree_root == NULL) + return; + + tw->tree.maxwidth = tw->tree.maxheight = 0; + for (i = 0, dp = tw->tree.largest; i < tw->tree.n_largest; i++, dp++) + *dp = 0; + initialize_dimensions (&tw->tree.largest, &tw->tree.n_largest, + tw->tree.n_largest); + compute_bounding_box_subtree (tw, tw->tree.tree_root, 0); + + /* + * Second pass to do final layout. Each child's bounding box is stacked + * on top of (if horizontal, else next to) on top of its siblings. The + * parent is centered between the first and last children. + */ + arrange_subtree (tw, tw->tree.tree_root, 0, 0, 0); + + /* + * Move each widget into place. + */ + set_tree_size (tw, insetvalues, tw->tree.maxwidth, tw->tree.maxheight); + set_positions (tw, tw->tree.tree_root, 0); + + /* + * And redisplay. + */ + if (XtIsRealized ((Widget) tw)) { + XClearArea (XtDisplay(tw), XtWindow((Widget)tw), 0, 0, 0, 0, True); + } +} + + + +/***************************************************************************** + * * + * Public Routines * + * * + *****************************************************************************/ + +void +XawTreeForceLayout(Widget tree) +{ + layout_tree ((TreeWidget) tree, FALSE); +} + diff --git a/src/Vendor.c b/src/Vendor.c new file mode 100644 index 0000000..12618e9 --- /dev/null +++ b/src/Vendor.c @@ -0,0 +1,524 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * This is a copy of Xt/Vendor.c with an additional ClassInitialize + * procedure to register Xmu resource type converters, and all the + * monkey business associated with input methods... + * + */ + +/* Make sure all wm properties can make it out of the resource manager */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The following two headers are for the input method. */ + +#include +#include + +/* + * Class Methods + */ +static void XawVendorShellChangeManaged(Widget); +static Boolean XawCvtCompoundTextToString(Display*, XrmValuePtr, Cardinal*, + XrmValue*, XrmValue*, XtPointer*); +static void XawVendorShellClassInitialize(void); +static XtGeometryResult XawVendorShellGeometryManager(Widget, + XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawVendorShellExtClassInitialize(void); +static void XawVendorShellExtDestroy(Widget); +static void XawVendorShellExtInitialize(Widget, Widget, ArgList, Cardinal*); +void XawVendorShellExtResize(Widget); +static Boolean XawVendorShellExtSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static void XawVendorShellClassPartInit(WidgetClass); +static void XawVendorShellInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawVendorShellRealize(Widget, Mask*, XSetWindowAttributes*); +static Boolean XawVendorShellSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * External + */ +void XawVendorStructureNotifyHandler(Widget, XtPointer, XEvent*, Boolean*); + +static XtResource resources[] = { + {XtNinput, XtCInput, XtRBool, sizeof(Bool), + XtOffsetOf(VendorShellRec, wm.wm_hints.input), + XtRImmediate, (XtPointer)True} +}; + +/*************************************************************************** + * + * Vendor shell class record + * + ***************************************************************************/ + +#if defined(__UNIXOS2__) || defined(__CYGWIN__) || defined(__MINGW32__) +/* to fix the EditRes problem because of wrong linker semantics */ +extern WidgetClass vendorShellWidgetClass; /* from Xt/Vendor.c */ +extern VendorShellClassRec _XawVendorShellClassRec; +extern void _XawFixupVendorShell(); + +#if defined(__UNIXOS2__) +unsigned long _DLL_InitTerm(unsigned long mod,unsigned long flag) +{ + switch (flag) { + case 0: /*called on init*/ + _CRT_init(); + vendorShellWidgetClass = (WidgetClass)(&_XawVendorShellClassRec); + _XawFixupVendorShell(); + return 1; + case 1: /*called on exit*/ + return 1; + default: + return 0; + } +} +#endif + +#if defined(__CYGWIN__) || defined(__MINGW32__) +int __stdcall +DllMain(unsigned long mod_handle, unsigned long flag, void *routine) +{ + switch (flag) + { + case 1: /* DLL_PROCESS_ATTACH - process attach */ + vendorShellWidgetClass = (WidgetClass)(&_XawVendorShellClassRec); + _XawFixupVendorShell(); + break; + case 0: /* DLL_PROCESS_DETACH - process detach */ + break; + } + return 1; +} +#endif + +#define vendorShellClassRec _XawVendorShellClassRec + +#endif + +static CompositeClassExtensionRec vendorCompositeExt = { + /* next_extension */ NULL, + /* record_type */ NULLQUARK, + /* version */ XtCompositeExtensionVersion, + /* record_size */ sizeof (CompositeClassExtensionRec), + /* accepts_objects */ TRUE, + /* allows_change_managed_set */ FALSE +}; + +#define SuperClass (&wmShellClassRec) +externaldef(vendorshellclassrec) VendorShellClassRec vendorShellClassRec = { + { + /* superclass */ (WidgetClass)SuperClass, + /* class_name */ "VendorShell", + /* size */ sizeof(VendorShellRec), + /* class_initialize */ XawVendorShellClassInitialize, + /* class_part_init */ XawVendorShellClassPartInit, + /* Class init'ed ? */ FALSE, + /* initialize */ XawVendorShellInitialize, + /* initialize_hook */ NULL, + /* realize */ XawVendorShellRealize, + /* actions */ NULL, + /* num_actions */ 0, + /* resources */ resources, + /* resource_count */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ FALSE, + /* compress_exposure */ TRUE, + /* compress_enterleave*/ FALSE, + /* visible_interest */ FALSE, + /* destroy */ NULL, + /* resize */ XawVendorShellExtResize, + /* expose */ NULL, + /* set_values */ XawVendorShellSetValues, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* intrinsics version */ XtVersion, + /* callback offsets */ NULL, + /* tm_table */ NULL, + /* query_geometry */ NULL, + /* display_accelerator*/ NULL, + /* extension */ NULL + },{ + /* geometry_manager */ XawVendorShellGeometryManager, + /* change_managed */ XawVendorShellChangeManaged, + /* insert_child */ XtInheritInsertChild, + /* delete_child */ XtInheritDeleteChild, + /* extension */ (XtPointer) &vendorCompositeExt + },{ + /* extension */ NULL + },{ + /* extension */ NULL + },{ + /* extension */ NULL + } +}; + +#ifndef __UNIXOS2__ +externaldef(vendorshellwidgetclass) WidgetClass vendorShellWidgetClass = + (WidgetClass) (&vendorShellClassRec); +#endif + +/*************************************************************************** + * + * The following section is for the Vendor shell Extension class record + * + ***************************************************************************/ + +static XtResource ext_resources[] = { + {XtNinputMethod, XtCInputMethod, XtRString, sizeof(String), + XtOffsetOf(XawVendorShellExtRec, vendor_ext.im.input_method), + XtRString, (XtPointer)NULL}, + {XtNpreeditType, XtCPreeditType, XtRString, sizeof(String), + XtOffsetOf(XawVendorShellExtRec, vendor_ext.im.preedit_type), + XtRString, (XtPointer)"OverTheSpot,OffTheSpot,Root"}, + {XtNopenIm, XtCOpenIm, XtRBoolean, sizeof(Boolean), + XtOffsetOf(XawVendorShellExtRec, vendor_ext.im.open_im), + XtRImmediate, (XtPointer)TRUE}, + {XtNsharedIc, XtCSharedIc, XtRBoolean, sizeof(Boolean), + XtOffsetOf(XawVendorShellExtRec, vendor_ext.ic.shared_ic), + XtRImmediate, (XtPointer)FALSE} +}; + +externaldef(vendorshellextclassrec) XawVendorShellExtClassRec + xawvendorShellExtClassRec = { + { + /* superclass */ (WidgetClass)&objectClassRec, + /* class_name */ "VendorShellExt", + /* size */ sizeof(XawVendorShellExtRec), + /* class_initialize */ XawVendorShellExtClassInitialize, + /* class_part_initialize*/ NULL, + /* Class init'ed ? */ FALSE, + /* initialize */ XawVendorShellExtInitialize, + /* initialize_hook */ NULL, + /* pad */ NULL, + /* pad */ NULL, + /* pad */ 0, + /* resources */ ext_resources, + /* resource_count */ XtNumber(ext_resources), + /* xrm_class */ NULLQUARK, + /* pad */ FALSE, + /* pad */ FALSE, + /* pad */ FALSE, + /* pad */ FALSE, + /* destroy */ XawVendorShellExtDestroy, + /* pad */ NULL, + /* pad */ NULL, + /* set_values */ XawVendorShellExtSetValues, + /* set_values_hook */ NULL, + /* pad */ NULL, + /* get_values_hook */ NULL, + /* pad */ NULL, + /* version */ XtVersion, + /* callback_offsets */ NULL, + /* pad */ NULL, + /* pad */ NULL, + /* pad */ NULL, + /* extension */ NULL + },{ + /* extension */ NULL + } +}; + +externaldef(xawvendorshellwidgetclass) WidgetClass + xawvendorShellExtWidgetClass = (WidgetClass) (&xawvendorShellExtClassRec); + + +/*ARGSUSED*/ +static Boolean +XawCvtCompoundTextToString(Display *dpy, XrmValuePtr args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *cvt_data) +{ + XTextProperty prop; + char **list; + int count; + static char *mbs = NULL; + int len; + + prop.value = (unsigned char *)fromVal->addr; + prop.encoding = XA_COMPOUND_TEXT(dpy); + prop.format = 8; + prop.nitems = fromVal->size; + + if(XmbTextPropertyToTextList(dpy, &prop, &list, &count) < Success) { + XtAppWarningMsg(XtDisplayToApplicationContext(dpy), + "converter", "XmbTextPropertyToTextList", "XawError", + "conversion from CT to MB failed.", NULL, NULL); + return False; + } + len = strlen(*list); + toVal->size = len; + mbs = XtRealloc(mbs, len + 1); /* keep buffer because no one call free :( */ + strcpy(mbs, *list); + XFreeStringList(list); + toVal->addr = (XtPointer)mbs; + return True; +} + +static void +XawVendorShellClassInitialize(void) +{ + static XtConvertArgRec screenConvertArg[] = { + {XtWidgetBaseOffset, (XtPointer) XtOffsetOf(WidgetRec, core.screen), + sizeof(Screen *)} + }; + + XtAddConverter(XtRString, XtRCursor, XmuCvtStringToCursor, + screenConvertArg, XtNumber(screenConvertArg)); + + XtAddConverter(XtRString, XtRBitmap, XmuCvtStringToBitmap, + screenConvertArg, XtNumber(screenConvertArg)); + + XtSetTypeConverter("CompoundText", XtRString, XawCvtCompoundTextToString, + NULL, 0, XtCacheNone, NULL); +} + +static void +XawVendorShellClassPartInit(WidgetClass cclass) +{ + CompositeClassExtension ext; + VendorShellWidgetClass vsclass = (VendorShellWidgetClass)cclass; + + if ((ext = (CompositeClassExtension) + XtGetClassExtension (cclass, + XtOffsetOf(CompositeClassRec, + composite_class.extension), + NULLQUARK, 1L, (Cardinal) 0)) == NULL) { + ext = (CompositeClassExtension) XtNew (CompositeClassExtensionRec); + if (ext != NULL) { + ext->next_extension = vsclass->composite_class.extension; + ext->record_type = NULLQUARK; + ext->version = XtCompositeExtensionVersion; + ext->record_size = sizeof (CompositeClassExtensionRec); + ext->accepts_objects = TRUE; + ext->allows_change_managed_set = FALSE; + vsclass->composite_class.extension = (XtPointer) ext; + } + } +} + +#if defined(__osf__) || defined(__UNIXOS2__) || defined(__CYGWIN__) || defined(__MINGW32__) +/* stupid OSF/1 shared libraries have the wrong semantics */ +/* symbols do not get resolved external to the shared library */ +void _XawFixupVendorShell() +{ + transientShellWidgetClass->core_class.superclass = + (WidgetClass) &vendorShellClassRec; + topLevelShellWidgetClass->core_class.superclass = + (WidgetClass) &vendorShellClassRec; +} +#endif + +/* ARGSUSED */ +static void +XawVendorShellInitialize(Widget req, Widget cnew, + ArgList args, Cardinal *num_args) +{ + XtAddEventHandler(cnew, (EventMask) 0, TRUE, _XEditResCheckMessages, NULL); + XtAddEventHandler(cnew, (EventMask) 0, TRUE, XmuRegisterExternalAgent, NULL); + XtCreateWidget("shellext", xawvendorShellExtWidgetClass, + cnew, args, *num_args); +} + +/* ARGSUSED */ +static Boolean +XawVendorShellSetValues(Widget old, Widget ref, Widget cnew, + ArgList args, Cardinal *num_args) +{ + return FALSE; +} + +static void +XawVendorShellRealize(Widget wid, Mask *vmask, XSetWindowAttributes *attr) +{ + WidgetClass super = wmShellWidgetClass; + + /* Make my superclass do all the dirty work */ + + (*super->core_class.realize) (wid, vmask, attr); + _XawImRealize(wid); +} + + +static void +XawVendorShellExtClassInitialize(void) +{ +} + +/* ARGSUSED */ +static void +XawVendorShellExtInitialize(Widget req, Widget cnew, + ArgList args, Cardinal *num_args) +{ + _XawImInitialize(cnew->core.parent, cnew); +} + +/* ARGSUSED */ +static void +XawVendorShellExtDestroy(Widget w) +{ + _XawImDestroy( w->core.parent, w ); +} + +/* ARGSUSED */ +static Boolean +XawVendorShellExtSetValues(Widget old, Widget ref, Widget cnew, + ArgList args, Cardinal *num_args) +{ + return FALSE; +} + +void +XawVendorShellExtResize(Widget w) +{ + ShellWidget sw = (ShellWidget) w; + Widget childwid; + Cardinal i; + int core_height; + + _XawImResizeVendorShell( w ); + core_height = _XawImGetShellHeight( w ); + for( i = 0; i < sw->composite.num_children; i++ ) { + if( XtIsManaged( sw->composite.children[ i ] ) ) { + childwid = sw->composite.children[ i ]; + XtResizeWidget( childwid, sw->core.width, core_height, + childwid->core.border_width ); + } + } +} + +/*ARGSUSED*/ +void +XawVendorStructureNotifyHandler(Widget w, XtPointer closure, XEvent *event, + Boolean *continue_to_dispatch) +{ + XawVendorShellExtResize(w); +} + +/*ARGSUSED*/ +static XtGeometryResult +XawVendorShellGeometryManager(Widget wid, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + ShellWidget shell = (ShellWidget)(wid->core.parent); + XtWidgetGeometry my_request; + + if(shell->shell.allow_shell_resize == FALSE && XtIsRealized(wid)) + return(XtGeometryNo); + + if (request->request_mode & (CWX | CWY)) + return(XtGeometryNo); + + /* %%% worry about XtCWQueryOnly */ + my_request.request_mode = 0; + if (request->request_mode & CWWidth) { + my_request.width = request->width; + my_request.request_mode |= CWWidth; + } + if (request->request_mode & CWHeight) { + my_request.height = request->height + + _XawImGetImAreaHeight( wid ); + my_request.request_mode |= CWHeight; + } + if (request->request_mode & CWBorderWidth) { + my_request.border_width = request->border_width; + my_request.request_mode |= CWBorderWidth; + } + if (XtMakeGeometryRequest((Widget)shell, &my_request, NULL) + == XtGeometryYes) { + /* assert: if (request->request_mode & CWWidth) then + * shell->core.width == request->width + * assert: if (request->request_mode & CWHeight) then + * shell->core.height == request->height + * + * so, whatever the WM sized us to (if the Shell requested + * only one of the two) is now the correct child size + */ + + wid->core.width = shell->core.width; + wid->core.height = shell->core.height; + if (request->request_mode & CWBorderWidth) { + wid->core.x = wid->core.y = -request->border_width; + } + _XawImCallVendorShellExtResize(wid); + return XtGeometryYes; + } else return XtGeometryNo; +} + +static void +XawVendorShellChangeManaged(Widget wid) +{ + ShellWidget w = (ShellWidget) wid; + Widget* childP; + int i; + + (*SuperClass->composite_class.change_managed)(wid); + for (i = w->composite.num_children, childP = w->composite.children; + i; i--, childP++) { + if (XtIsManaged(*childP)) { + XtSetKeyboardFocus(wid, *childP); + break; + } + } +} diff --git a/src/Viewport.c b/src/Viewport.c new file mode 100644 index 0000000..082682f --- /dev/null +++ b/src/Viewport.c @@ -0,0 +1,1099 @@ +/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include "Private.h" + +/* + * Class Methods + */ +static Boolean Layout(FormWidget, unsigned int, unsigned int, Bool); +static void XawViewportChangeManaged(Widget); +static void XawViewportInitialize(Widget, Widget, ArgList, Cardinal*); +static void +XawViewportConstraintInitialize(Widget, Widget, ArgList, Cardinal*); +static XtGeometryResult XawViewportGeometryManager(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static XtGeometryResult XawViewportQueryGeometry(Widget, + XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawViewportRealize(Widget, XtValueMask*, XSetWindowAttributes*); +static void XawViewportResize(Widget); +static Boolean XawViewportSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); + +/* + * Prototypes + */ +static void ComputeLayout(Widget, Bool, Bool); +static void ComputeWithForceBars(Widget, Bool, XtWidgetGeometry*, + int*, int*); +static Widget CreateScrollbar(ViewportWidget, Bool); +static XtGeometryResult GeometryRequestPlusScrollbar(ViewportWidget, Bool, + XtWidgetGeometry*, + XtWidgetGeometry*); +static Bool GetGeometry(Widget, unsigned int, unsigned int); +static void MoveChild(ViewportWidget, int, int); +static XtGeometryResult QueryGeometry(ViewportWidget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void RedrawThumbs(ViewportWidget); +static void ScrollUpDownProc(Widget, XtPointer, XtPointer); +static void SendReport(ViewportWidget, unsigned int); +static void SetBar(Widget, int, unsigned int, unsigned int); +static XtGeometryResult TestSmaller(ViewportWidget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void ThumbProc(Widget, XtPointer, XtPointer); + +/* + * Initialization + */ +#define offset(field) XtOffsetOf(ViewportRec, viewport.field) +static XtResource resources[] = { + { + XtNforceBars, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(forcebars), + XtRImmediate, + (XtPointer)False + }, + { + XtNallowHoriz, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(allowhoriz), + XtRImmediate, + (XtPointer)False + }, + { + XtNallowVert, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(allowvert), + XtRImmediate, + (XtPointer)False + }, + { + XtNuseBottom, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(usebottom), + XtRImmediate, + (XtPointer)False + }, + { + XtNuseRight, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + offset(useright), + XtRImmediate, + (XtPointer)False + }, + { + XtNreportCallback, + XtCReportCallback, + XtRCallback, + sizeof(XtPointer), + offset(report_callbacks), + XtRImmediate, + NULL + }, +}; +#undef offset + +#define Superclass (&formClassRec) +ViewportClassRec viewportClassRec = { + /* core */ + { + (WidgetClass)Superclass, /* superclass */ + "Viewport", /* class_name */ + sizeof(ViewportRec), /* widget_size */ + XawInitializeWidgetSet, /* class_initialize */ + NULL, /* class_part_init */ + False, /* class_inited */ + XawViewportInitialize, /* initialize */ + NULL, /* initialize_hook */ + XawViewportRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + XawViewportResize, /* resize */ + XtInheritExpose, /* expose */ + XawViewportSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XawViewportQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* composite */ + { + XawViewportGeometryManager, /* geometry_manager */ + XawViewportChangeManaged, /* change_managed */ + XtInheritInsertChild, /* insert_child */ + XtInheritDeleteChild, /* delete_child */ + NULL, /* extension */ + }, + /* constraint */ + { + NULL, /* subresourses */ + 0, /* subresource_count */ + sizeof(ViewportConstraintsRec), /* constraint_size */ + XawViewportConstraintInitialize, /* initialize */ + NULL, /* destroy */ + NULL, /* set_values */ + NULL, /* extension */ + }, + /* form */ + { + Layout, /* layout */ + }, + /* viewport */ + { + NULL, /* extension */ + }, +}; + +WidgetClass viewportWidgetClass = (WidgetClass)&viewportClassRec; + +/* + * Implementation + */ +static Widget +CreateScrollbar(ViewportWidget w, Bool horizontal) +{ + static Arg barArgs[] = { + {XtNorientation, 0}, + {XtNlength, 0}, + {XtNleft, 0}, + {XtNright, 0}, + {XtNtop, 0}, + {XtNbottom, 0}, + {XtNmappedWhenManaged, False}, + }; + Widget clip = w->viewport.clip; + ViewportConstraints constraints = + (ViewportConstraints)clip->core.constraints; + Widget bar; + + XtSetArg(barArgs[0], XtNorientation, + horizontal ? XtorientHorizontal : XtorientVertical); + XtSetArg(barArgs[1], XtNlength, + horizontal ? XtWidth(clip) : XtHeight(clip)); + XtSetArg(barArgs[2], XtNleft, + !horizontal && w->viewport.useright ? XtChainRight : XtChainLeft); + XtSetArg(barArgs[3], XtNright, + !horizontal && !w->viewport.useright ? XtChainLeft : XtChainRight); + XtSetArg(barArgs[4], XtNtop, + horizontal && w->viewport.usebottom ? XtChainBottom: XtChainTop); + XtSetArg(barArgs[5], XtNbottom, + horizontal && !w->viewport.usebottom ? XtChainTop: XtChainBottom); + + bar = XtCreateWidget(horizontal ? "horizontal" : "vertical", + scrollbarWidgetClass, (Widget)w, + barArgs, XtNumber(barArgs)); + XtAddCallback(bar, XtNscrollProc, ScrollUpDownProc, (XtPointer)w); + XtAddCallback(bar, XtNjumpProc, ThumbProc, (XtPointer)w); + + if (horizontal) { + w->viewport.horiz_bar = bar; + constraints->form.vert_base = bar; + } + else { + w->viewport.vert_bar = bar; + constraints->form.horiz_base = bar; + } + + XtManageChild(bar); + + return (bar); +} + +/*ARGSUSED*/ +static void +XawViewportInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + ViewportWidget w = (ViewportWidget)cnew; + static Arg clip_args[8]; + Cardinal arg_cnt; + Widget h_bar, v_bar; + Dimension clip_height, clip_width; + + w->form.default_spacing = 0; /* Reset the default spacing to 0 pixels */ + + /* + * Initialize all widget pointers to NULL + */ + w->viewport.child = NULL; + w->viewport.horiz_bar = w->viewport.vert_bar = NULL; + + /* + * Create Clip Widget + */ + arg_cnt = 0; + XtSetArg(clip_args[arg_cnt], XtNbackgroundPixmap, None); arg_cnt++; + XtSetArg(clip_args[arg_cnt], XtNborderWidth, 0); arg_cnt++; + XtSetArg(clip_args[arg_cnt], XtNleft, XtChainLeft); arg_cnt++; + XtSetArg(clip_args[arg_cnt], XtNright, XtChainRight); arg_cnt++; + XtSetArg(clip_args[arg_cnt], XtNtop, XtChainTop); arg_cnt++; + XtSetArg(clip_args[arg_cnt], XtNbottom, XtChainBottom); arg_cnt++; + XtSetArg(clip_args[arg_cnt], XtNwidth, XtWidth(w)); arg_cnt++; + XtSetArg(clip_args[arg_cnt], XtNheight, XtHeight(w)); arg_cnt++; + + w->viewport.clip = XtCreateManagedWidget("clip", widgetClass, cnew, + clip_args, arg_cnt); + + if (!w->viewport.forcebars) + return; /* If we are not forcing the bars then we are done */ + + if (w->viewport.allowhoriz) + (void)CreateScrollbar(w, True); + if (w->viewport.allowvert) + (void)CreateScrollbar(w, False); + + h_bar = w->viewport.horiz_bar; + v_bar = w->viewport.vert_bar; + + /* + * Set the clip widget to the correct height + */ + clip_width = XtWidth(w); + clip_height = XtHeight(w); + + if (h_bar != NULL && XtWidth(w) > XtWidth(h_bar) + XtBorderWidth(h_bar)) + clip_width -= XtWidth(h_bar) + XtBorderWidth(h_bar); + + if (v_bar != NULL && XtHeight(w) > XtHeight(v_bar) + XtBorderWidth(v_bar)) + clip_height -= XtHeight(v_bar) + XtBorderWidth(v_bar); + + arg_cnt = 0; + XtSetArg(clip_args[arg_cnt], XtNwidth, clip_width); arg_cnt++; + XtSetArg(clip_args[arg_cnt], XtNheight, clip_height); arg_cnt++; + XtSetValues(w->viewport.clip, clip_args, arg_cnt); +} + +/*ARGSUSED*/ +static void +XawViewportConstraintInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + ((ViewportConstraints)cnew->core.constraints)->viewport.reparented = False; +} + +static void +XawViewportRealize(Widget widget, XtValueMask *value_mask, + XSetWindowAttributes *attributes) +{ + ViewportWidget w = (ViewportWidget)widget; + Widget child = w->viewport.child; + Widget clip = w->viewport.clip; + + *value_mask |= CWBitGravity; + attributes->bit_gravity = NorthWestGravity; + (*Superclass->core_class.realize)(widget, value_mask, attributes); + + (*w->core.widget_class->core_class.resize)(widget); /* turn on bars */ + + if (child != NULL) { + XtMoveWidget(child, 0, 0); + XtRealizeWidget(clip); + XtRealizeWidget(child); + XReparentWindow(XtDisplay(w), XtWindow(child), XtWindow(clip), 0, 0); + XtMapWidget(child); + } +} + +/*ARGSUSED*/ +static Boolean +XawViewportSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + ViewportWidget w = (ViewportWidget)cnew; + ViewportWidget cw = (ViewportWidget)current; + + if (w->viewport.forcebars != cw->viewport.forcebars + || w->viewport.allowvert != cw->viewport.allowvert + || w->viewport.allowhoriz != cw->viewport.allowhoriz + || w->viewport.useright != cw->viewport.useright + || w->viewport.usebottom != cw->viewport.usebottom) + (*w->core.widget_class->core_class.resize)(cnew); /* Recompute layout */ + + return (False); +} + +static void +XawViewportChangeManaged(Widget widget) +{ + ViewportWidget w = (ViewportWidget)widget; + int num_children = w->composite.num_children; + Widget child, *childP; + int i; + + child = NULL; + for (childP = w->composite.children, + i = 0; i < num_children; + childP++, i++) { + if (XtIsManaged(*childP) + && *childP != w->viewport.clip + && *childP != w->viewport.horiz_bar + && *childP != w->viewport.vert_bar) { + child = *childP; + break; + } + } + + if (child != w->viewport.child) { + w->viewport.child = child; + if (child != NULL) { + XtResizeWidget(child, XtWidth(child), XtHeight(child), 0); + if (XtIsRealized(widget)) { + ViewportConstraints constraints = + (ViewportConstraints)child->core.constraints; + if (!XtIsRealized(child)) { + Window window = XtWindow(w); + + XtMoveWidget(child, 0, 0); + w->core.window = XtWindow(w->viewport.clip); + XtRealizeWidget(child); + w->core.window = window; + constraints->viewport.reparented = True; + } + else if (!constraints->viewport.reparented) { + XReparentWindow(XtDisplay(w), XtWindow(child), + XtWindow(w->viewport.clip), 0, 0); + constraints->viewport.reparented = True; + if (child->core.mapped_when_managed) + XtMapWidget(child); + } + } + GetGeometry(widget, XtWidth(child), XtHeight(child)); + (*((ViewportWidgetClass)w->core.widget_class)->form_class.layout) + ((FormWidget)w, XtWidth(w), XtHeight(w), True /* True? */); + } + } + +#ifdef notdef + (*Superclass->composite_class.change_managed)(widget); +#endif +} + +static void +SetBar(Widget w, int top, unsigned int length, unsigned int total) +{ + XawScrollbarSetThumb(w, (float)top / (float)total, + (float)length / (float)total); +} + +static void +RedrawThumbs(ViewportWidget w) +{ + Widget child = w->viewport.child; + Widget clip = w->viewport.clip; + + if (w->viewport.horiz_bar != NULL) + SetBar(w->viewport.horiz_bar, -(int)XtX(child), + XtWidth(clip), XtWidth(child)); + + if (w->viewport.vert_bar != NULL) + SetBar(w->viewport.vert_bar, -(int)XtY(child), + XtHeight(clip), XtHeight(child)); +} + +static void +SendReport(ViewportWidget w, unsigned int changed) +{ + XawPannerReport rep; + + if (w->viewport.report_callbacks) { + Widget child = w->viewport.child; + Widget clip = w->viewport.clip; + + rep.changed = changed; + rep.slider_x = -XtX(child); /* child is canvas */ + rep.slider_y = -XtY(child); /* clip is slider */ + rep.slider_width = XtWidth(clip); + rep.slider_height = XtHeight(clip); + rep.canvas_width = XtWidth(child); + rep.canvas_height = XtHeight(child); + XtCallCallbackList((Widget)w, w->viewport.report_callbacks, + (XtPointer)&rep); + } +} + +static void +MoveChild(ViewportWidget w, int x, int y) +{ + Widget child = w->viewport.child; + Widget clip = w->viewport.clip; + + /* make sure we never move past right/bottom borders */ + if (-x + (int)XtWidth(clip) > XtWidth(child)) + x = -(int)(XtWidth(child) - XtWidth(clip)); + + if (-y + (int)XtHeight(clip) > XtHeight(child)) + y = -(int)(XtHeight(child) - XtHeight(clip)); + + /* make sure we never move past left/top borders */ + if (x >= 0) + x = 0; + if (y >= 0) + y = 0; + + XtMoveWidget(child, x, y); + SendReport(w, (XawPRSliderX | XawPRSliderY)); + + RedrawThumbs(w); +} + +static void +ComputeLayout(Widget widget, Bool query, Bool destroy_scrollbars) +{ + ViewportWidget w = (ViewportWidget)widget; + Widget child = w->viewport.child; + Widget clip = w->viewport.clip; + ViewportConstraints constraints = + (ViewportConstraints)clip->core.constraints; + Bool needshoriz, needsvert; + int clip_width, clip_height; + XtWidgetGeometry intended; + + if (child == NULL) + return; + + clip_width = XtWidth(w); + clip_height = XtHeight(w); + intended.request_mode = CWBorderWidth; + intended.border_width = 0; + + if (w->viewport.forcebars) { + needsvert = w->viewport.allowvert; + needshoriz = w->viewport.allowhoriz; + ComputeWithForceBars(widget, query, &intended, + &clip_width, &clip_height); + } + else { + Dimension prev_width, prev_height; + XtGeometryMask prev_mode; + XtWidgetGeometry preferred; + + needshoriz = needsvert = False; + + /* + * intended.{width,height} caches the eventual child dimensions, + * but we don't set the mode bits until after we decide that the + * child's preferences are not acceptable + */ + if (!w->viewport.allowhoriz) + intended.request_mode |= CWWidth; + + if (XtWidth(child) < clip_width) + intended.width = clip_width; + else + intended.width = XtWidth(child); + + if (XtHeight(child) < clip_height) + intended.height = clip_height; + else + intended.height = XtHeight(child); + + if (!w->viewport.allowvert) + intended.request_mode |= CWHeight; + + if (!query) { + preferred.width = XtWidth(child); + preferred.height = XtHeight(child); + } + do { /* while intended != prev */ + if (query) { + (void)XtQueryGeometry(child, &intended, &preferred); + if (!(preferred.request_mode & CWWidth)) + preferred.width = intended.width; + if (!(preferred.request_mode & CWHeight)) + preferred.height = intended.height; + } + prev_width = intended.width; + prev_height = intended.height; + prev_mode = intended.request_mode; + /* + * note that having once decided to turn on either bar + * we'll not change our mind until we're next resized, + * thus avoiding potential oscillations + */ +#define CheckHoriz() \ + if (w->viewport.allowhoriz && \ + preferred.width > clip_width) { \ + if (!needshoriz) { \ + Widget bar; \ + \ + needshoriz = True; \ + if ((bar = w->viewport.horiz_bar) == NULL) \ + bar = CreateScrollbar(w, True); \ + clip_height -= XtHeight(bar) + XtBorderWidth(bar); \ + if (clip_height < 1) \ + clip_height = 1; \ + } \ + intended.width = preferred.width; \ + } + + CheckHoriz(); + if (w->viewport.allowvert && preferred.height > clip_height) { + if (!needsvert) { + Widget bar; + needsvert = True; + if ((bar = w->viewport.vert_bar) == NULL) + bar = CreateScrollbar(w, False); + clip_width -= XtWidth(bar) + XtBorderWidth(bar); + if (clip_width < 1) + clip_width = 1; + CheckHoriz(); + } + intended.height = preferred.height; + } + if (!w->viewport.allowhoriz || preferred.width < clip_width) { + intended.width = clip_width; + intended.request_mode |= CWWidth; + } + if (!w->viewport.allowvert || preferred.height < clip_height) { + intended.height = clip_height; + intended.request_mode |= CWHeight; + } + } while (intended.request_mode != prev_mode + || (intended.request_mode & CWWidth + && intended.width != prev_width) + || (intended.request_mode & CWHeight + && intended.height != prev_height)); + } + + if (XtIsRealized(clip)) + XRaiseWindow(XtDisplay(clip), XtWindow(clip)); + + XtMoveWidget(clip, + needsvert ? w->viewport.useright ? 0 : + XtWidth(w->viewport.vert_bar) + + XtBorderWidth(w->viewport.vert_bar) : 0, + needshoriz ? w->viewport.usebottom ? 0 : + XtHeight(w->viewport.horiz_bar) + + XtBorderWidth(w->viewport.horiz_bar) : 0); + XtResizeWidget(clip, clip_width, clip_height, 0); + + if (w->viewport.horiz_bar != NULL) { + Widget bar = w->viewport.horiz_bar; + + if (!needshoriz) { + constraints->form.vert_base = NULL; + if (destroy_scrollbars) { + XtDestroyWidget(bar); + w->viewport.horiz_bar = NULL; + } + } + else { + int bw = XtBorderWidth(bar); + + XtResizeWidget(bar, clip_width, XtHeight(bar), bw); + XtMoveWidget(bar, + needsvert && !w->viewport.useright + ? XtWidth(w->viewport.vert_bar) : -bw, + w->viewport.usebottom + ? XtHeight(w) - XtHeight(bar) - bw : -bw); + XtSetMappedWhenManaged(bar, True); + } + } + + if (w->viewport.vert_bar != NULL) { + Widget bar = w->viewport.vert_bar; + + if (!needsvert) { + constraints->form.horiz_base = NULL; + if (destroy_scrollbars) { + XtDestroyWidget(bar); + w->viewport.vert_bar = NULL; + } + } + else { + int bw = bar->core.border_width; + + XtResizeWidget(bar, XtWidth(bar), clip_height, bw); + XtMoveWidget(bar, + w->viewport.useright + ? XtWidth(w) - XtWidth(bar) - bw : -bw, + needshoriz && !w->viewport.usebottom + ? XtHeight(w->viewport.horiz_bar) : -bw); + XtSetMappedWhenManaged(bar, True); + } + } + + if (child != NULL) { + XtResizeWidget(child, intended.width, intended.height, 0); + MoveChild(w, needshoriz ? XtX(child) : 0, needsvert ? XtY(child) : 0); + } + + SendReport (w, XawPRAll); +} + +/* + * Function: + * ComputeWithForceBars + * + * Parameters: + * widget - viewport widget + * query - whether or not to query the child + * intended - cache of the childs height is stored here + * (used and returned) + * clip_width - size of clip window (used and returned) + * clip_height - "" + * + * Description: + * Computes the layout give forcebars is set. + */ +static void +ComputeWithForceBars(Widget widget, Bool query, XtWidgetGeometry *intended, + int *clip_width, int *clip_height) +{ + ViewportWidget w = (ViewportWidget)widget; + Widget child = w->viewport.child; + XtWidgetGeometry preferred; + + /* + * If forcebars then needs = allows = has + * Thus if needsvert is set it MUST have a scrollbar + */ + if (w->viewport.allowvert) { + if (w->viewport.vert_bar == NULL) + w->viewport.vert_bar = CreateScrollbar(w, False); + + *clip_width -= XtWidth(w->viewport.vert_bar) + + XtBorderWidth(w->viewport.vert_bar); + } + + if (w->viewport.allowhoriz) { + if (w->viewport.horiz_bar == NULL) + w->viewport.horiz_bar = CreateScrollbar(w, True); + + *clip_height -= XtHeight(w->viewport.horiz_bar) + + XtBorderWidth(w->viewport.horiz_bar); + } + + AssignMax(*clip_width, 1); + AssignMax(*clip_height, 1); + + if (!w->viewport.allowvert) { + intended->height = *clip_height; + intended->request_mode = CWHeight; + } + if (!w->viewport.allowhoriz) { + intended->width = *clip_width; + intended->request_mode = CWWidth; + } + + if (query) { + if (w->viewport.allowvert || w->viewport.allowhoriz) { + XtQueryGeometry(child, intended, &preferred); + + if (!(intended->request_mode & CWWidth)) { + if (preferred.request_mode & CWWidth) + intended->width = preferred.width; + else + intended->width = XtWidth(child); + } + + if (!(intended->request_mode & CWHeight)) { + if (preferred.request_mode & CWHeight) + intended->height = preferred.height; + else + intended->height = XtHeight(child); + } + } + } + else { + if (w->viewport.allowvert) + intended->height = XtHeight(child); + if (w->viewport.allowhoriz) + intended->width = XtWidth(child); + } + + if (*clip_width > (int)intended->width) + intended->width = *clip_width; + if (*clip_height > (int)intended->height) + intended->height = *clip_height; +} + +static void +XawViewportResize(Widget widget) +{ + ComputeLayout(widget, True, True); +} + +/*ARGSUSED*/ +static Boolean +Layout(FormWidget w, unsigned int width, unsigned int height, Bool force) +{ + ComputeLayout((Widget)w, True, True); + w->form.preferred_width = XtWidth(w); + w->form.preferred_height = XtHeight(w); + + return (False); +} + +static void +ScrollUpDownProc(Widget widget, XtPointer closure, XtPointer call_data) +{ + ViewportWidget w = (ViewportWidget)closure; + Widget child = w->viewport.child; + int pix = (long)call_data; + int x, y; + + if (child == NULL) + return; + + x = XtX(child) - (widget == w->viewport.horiz_bar ? pix : 0); + y = XtY(child) - (widget == w->viewport.vert_bar ? pix : 0); + MoveChild(w, x, y); +} + +/*ARGSUSED*/ +static void +ThumbProc(Widget widget, XtPointer closure, XtPointer call_data) +{ + ViewportWidget w = (ViewportWidget)closure; + Widget child = w->viewport.child; + float percent = *(float *)call_data; + int x, y; + + if (child == NULL) + return; + + if (widget == w->viewport.horiz_bar) + x = -percent * XtWidth(child); + else + x = XtX(child); + + if (widget == w->viewport.vert_bar) + y = -percent * XtHeight(child); + else + y = XtY(child); + + MoveChild(w, x, y); +} + +static XtGeometryResult +TestSmaller(ViewportWidget w, XtWidgetGeometry *request, + XtWidgetGeometry *reply_return) +{ + if (request->width < XtWidth(w) || request->height < XtHeight(w)) + return (XtMakeGeometryRequest((Widget)w, request, reply_return)); + + return (XtGeometryYes); +} + +static XtGeometryResult +GeometryRequestPlusScrollbar(ViewportWidget w, Bool horizontal, + XtWidgetGeometry *request, + XtWidgetGeometry *reply_return) +{ + Widget sb; + XtWidgetGeometry plusScrollbars; + + plusScrollbars = *request; + if ((sb = w->viewport.horiz_bar) == NULL) + sb = CreateScrollbar(w, horizontal); + request->width += XtWidth(sb); + request->height += XtHeight(sb); + XtDestroyWidget(sb); + return (XtMakeGeometryRequest((Widget)w, &plusScrollbars, reply_return)); +} + +#define WidthChange() (request->width != XtWidth(w)) +#define HeightChange() (request->height != XtHeight(w)) +static XtGeometryResult +QueryGeometry(ViewportWidget w, XtWidgetGeometry *request, + XtWidgetGeometry *reply_return) +{ + if (w->viewport.allowhoriz && w->viewport.allowvert) + return (TestSmaller(w, request, reply_return)); + + else if (w->viewport.allowhoriz && !w->viewport.allowvert) { + if (WidthChange() && !HeightChange()) + return (TestSmaller(w, request, reply_return)); + else if (!WidthChange() && HeightChange()) + return (XtMakeGeometryRequest((Widget)w, request, reply_return)); + else if (WidthChange() && HeightChange()) + return (GeometryRequestPlusScrollbar(w, True, request, reply_return)); + else /* !WidthChange() && !HeightChange() */ + return (XtGeometryYes); + } + else if (!w->viewport.allowhoriz && w->viewport.allowvert) { + if (!WidthChange() && HeightChange()) + return (TestSmaller(w, request, reply_return)); + else if (WidthChange() && !HeightChange()) + return (XtMakeGeometryRequest((Widget)w, request, reply_return)); + else if (WidthChange() && HeightChange()) + return (GeometryRequestPlusScrollbar(w, False, request, reply_return)); + else /* !WidthChange() && !HeightChange() */ + return (XtGeometryYes); + } + else /* (!w->viewport.allowhoriz && !w->viewport.allowvert) */ + return (XtMakeGeometryRequest((Widget)w, request, reply_return)); +} +#undef WidthChange +#undef HeightChange + +static XtGeometryResult +XawViewportGeometryManager(Widget child, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + ViewportWidget w = (ViewportWidget)child->core.parent; + Bool rWidth = (request->request_mode & CWWidth) != 0; + Bool rHeight = (request->request_mode & CWHeight) != 0; + XtWidgetGeometry allowed; + XtGeometryResult result; + Bool reconfigured; + Bool child_changed_size; + unsigned int height_remaining; + + if (request->request_mode & XtCWQueryOnly) + return (QueryGeometry(w, request, reply)); + + if (child != w->viewport.child + || request->request_mode & ~(CWWidth | CWHeight | CWBorderWidth) + || ((request->request_mode & CWBorderWidth) + && request->border_width > 0)) + return (XtGeometryNo); + + allowed = *request; + + reconfigured = GetGeometry((Widget)w, + rWidth ? request->width : XtWidth(w), + rHeight ? request->height : XtHeight(w)); + + child_changed_size = (rWidth && XtWidth(child) != request->width) || + (rHeight && XtHeight(child) != request->height); + + height_remaining = XtHeight(w); + if (rWidth && XtWidth(w) != request->width) { + if (w->viewport.allowhoriz && request->width > XtWidth(w)) { + /* horizontal scrollbar will be needed so possibly reduce height */ + Widget bar; + + if ((bar = w->viewport.horiz_bar) == NULL) + bar = CreateScrollbar(w, True); + height_remaining -= XtHeight(bar) + XtBorderWidth(bar); + reconfigured = True; + } + else + allowed.width = XtWidth(w); + } + if (rHeight && height_remaining != request->height) { + if (w->viewport.allowvert && request->height > height_remaining) { + /* vertical scrollbar will be needed, so possibly reduce width */ + if (!w->viewport.allowhoriz || request->width < XtWidth(w)) { + Widget bar; + + if ((bar = w->viewport.vert_bar) == NULL) + bar = CreateScrollbar(w, False); + if (!rWidth) { + allowed.width = XtWidth(w); + allowed.request_mode |= CWWidth; + } + if (allowed.width > XtWidth(bar) + XtBorderWidth(bar)) + allowed.width -= XtWidth(bar) + XtBorderWidth(bar); + else + allowed.width = 1; + reconfigured = True; + } + } + else + allowed.height = height_remaining; + } + + if (allowed.width != request->width || allowed.height != request->height) { + *reply = allowed; + result = XtGeometryAlmost; + } + else { + if (rWidth) + XtWidth(child) = request->width; + if (rHeight) + XtHeight(child) = request->height; + result = XtGeometryYes; + } + + if (reconfigured || child_changed_size) + ComputeLayout((Widget)w, False, result == XtGeometryYes); + + return (result); +} + +static Bool +GetGeometry(Widget w, unsigned int width, unsigned int height) +{ + XtWidgetGeometry geometry, return_geom; + XtGeometryResult result; + + if (width == XtWidth(w) && height == XtHeight(w)) + return (False); + + geometry.request_mode = CWWidth | CWHeight; + geometry.width = width; + geometry.height = height; + + if (XtIsRealized(w)) { + if (((ViewportWidget)w)->viewport.allowhoriz && width > XtWidth(w)) + geometry.width = XtWidth(w); + if (((ViewportWidget)w)->viewport.allowvert && height > XtHeight(w)) + geometry.height = XtHeight(w); + } + else { + /* This is the Realize call; we'll inherit a w&h iff none currently */ + if (XtWidth(w) != 0) { + if (XtHeight(w) != 0) + return (False); + geometry.width = XtWidth(w); + } + if (XtHeight(w) != 0) + geometry.height = XtHeight(w); + } + + result = XtMakeGeometryRequest(w, &geometry, &return_geom); + if (result == XtGeometryAlmost) + result = XtMakeGeometryRequest(w, &return_geom, NULL); + + return (result == XtGeometryYes); +} + +static XtGeometryResult +XawViewportQueryGeometry(Widget w, XtWidgetGeometry *constraints, + XtWidgetGeometry *reply) +{ + if (((ViewportWidget)w)->viewport.child != NULL) + return (XtQueryGeometry(((ViewportWidget)w)->viewport.child, + constraints, reply)); + + return (XtGeometryYes); +} + +void +XawViewportSetLocation +( + Widget gw, +#if NeedWidePrototypes + double xoff, double yoff +#else + float xoff, float yoff +#endif + ) +{ + ViewportWidget w = (ViewportWidget)gw; + Widget child = w->viewport.child; + int x, y; + + if (xoff > 1.0) /* scroll to right */ + x = XtWidth(child); + else if (xoff < 0.0) /* if the offset is < 0.0 nothing */ + x = XtX(child); + else + x = (float)XtWidth(child) * xoff; + + if (yoff > 1.0) + y = XtHeight(child); + else if (yoff < 0.0) + y = XtY(child); + else + y = (float)XtHeight(child) * yoff; + + MoveChild (w, -x, -y); +} + +void +XawViewportSetCoordinates(Widget gw, +#if NeedWidePrototypes + int x, int y +#else + Position x, Position y +#endif +) +{ + ViewportWidget w = (ViewportWidget)gw; + Widget child = w->viewport.child; + + if (x > XtWidth(child)) + x = XtWidth(child); + else if (x < 0) + x = XtX(child); + + if (y > XtHeight(child)) + y = XtHeight(child); + else if (y < 0) + y = XtY(child); + + MoveChild (w, -x, -y); +} diff --git a/src/XawI18n.c b/src/XawI18n.c new file mode 100644 index 0000000..99ed2ca --- /dev/null +++ b/src/XawI18n.c @@ -0,0 +1,105 @@ +/* Copyright 1991 NCR Corporation - Dayton, Ohio, USA */ + +/* + * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, + * and Nippon Telegraph and Telephone Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of OMRON, NTT Software, and NTT + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. OMRON, NTT Software, + * and NTT make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * OMRON, NTT SOFTWARE, AND NTT, DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, OR NTT BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + +/* + +Copyright 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include "XawI18n.h" + +wchar_t +#if NeedWidePrototypes +_Xaw_atowc(int c) +#else +_Xaw_atowc(unsigned char c) +#endif +{ + wchar_t wc; + char str[2]; + + str[0] = c; + str[1] = '\0'; + + mbtowc(&wc, str, 1); + + return (wc); +} + +#ifdef NCR +int +_Xaw_iswspace(wchar_t w) +{ + int ret = 0; + wchar_t s = _Xaw_atowc(' '); + + if (s == w) + ret = 1; + + return (ret); +} +#endif + +int +_Xaw_iswalnum(wchar_t ch) +{ +#ifdef HAVE_ISWALNUM + return iswalnum(ch); +#else + unsigned char mb[MB_LEN_MAX]; + + wctomb((char*)mb, ch); + + return (isalnum(*mb)); +#endif +} diff --git a/src/XawI18n.h b/src/XawI18n.h new file mode 100644 index 0000000..d50171c --- /dev/null +++ b/src/XawI18n.h @@ -0,0 +1,118 @@ +/************************************************************ + +Copyright 1993, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +********************************************************/ + +#ifdef HAVE_WCTYPE_H +#include +#ifdef HAVE_WIDEC_H +#include +#define wcslen(c) wslen(c) +#define wcscpy(d, s) wscpy(d, s) +#define wcsncpy(d, s, l) wsncpy(d, s, l) +#endif +#endif + +#ifdef HAVE_WCHAR_H +#include +#endif + +#if defined(AIXV3) || defined(__SCO__) +#include +#endif + +#ifdef NCR +#define iswspace(c) _Xaw_iswspace(c) +int _Xaw_iswspace +( + wchar_t c + ); +#endif + +#ifdef sony +#ifndef SVR4 +#include +#define iswspace(c) jisspace(c) +#endif +#endif + +#ifdef QNX4 +#define toascii( c ) ((unsigned)(c) & 0x007f) +#endif + +#include + +#ifdef USE_XWCHAR_STRING +int _Xwcslen +( + wchar_t *wstr + ); + +#define wcslen(c) _Xwcslen(c) + +wchar_t *_Xwcscpy +( + wchar_t *wstr1, + wchar_t *wstr2 + ); + +#define wcscpy(d,s) _Xwcscpy(d,s) + +wchar_t *_Xwcsncpy +( + wchar_t *wstr1, + wchar_t *wstr2, + int len + ); + +#define wcsncpy(d, s, l) _Xwcsncpy(d, s, l) + +#ifdef USE_XMBTOWC +#define mbtowc(wc, s, l) _Xmbtowc(wc, s, l) +#endif +#endif + +wchar_t _Xaw_atowc +( +#if NeedWidePrototypes + int c +#else + unsigned char c +#endif + ); + +#ifndef HAS_ISW_FUNCS +#include +#ifndef iswspace +#define iswspace(c) (isascii(c) && isspace(toascii(c))) +#endif +#endif + +#if !defined(iswalnum) && !defined(HAVE_ISWALNUM) +#define iswalnum(c) _Xaw_iswalnum(c) +#endif +int _Xaw_iswalnum +( + wchar_t c + ); diff --git a/src/XawIm.c b/src/XawIm.c new file mode 100644 index 0000000..7a7152f --- /dev/null +++ b/src/XawIm.c @@ -0,0 +1,1609 @@ +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of OMRON not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. OMRON makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Seiji Kuwari OMRON Corporation + * kuwa@omron.co.jp + * kuwa%omron.co.jp@uunet.uu.net + */ + + +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "XawI18n.h" +#include + +#include + +#define maxAscentOfFontSet(fontset) \ + ( - (XExtentsOfFontSet((fontset)))->max_logical_extent.y) + +#define maxHeightOfFontSet(fontset) \ + ((XExtentsOfFontSet((fontset)))->max_logical_extent.height) + +#define maxDescentOfFontSet(fontset) \ + (maxHeightOfFontSet(fontset) - maxAscentOfFontSet(fontset)) + +#define Offset(field) (XtOffsetOf(XawIcTablePart, field)) + +/***************************************************** + * + * Forward reference prototypes + * + *****************************************************/ + +/* + * Prototypes + */ +static void AllCreateIC(XawVendorShellExtPart*); +static void CloseIM(XawVendorShellExtPart*); +static void CompileResourceList(XtResourceList, unsigned int); +static void ConfigureCB(Widget, XtPointer, XEvent*, Boolean*); +static void CreateIC(Widget, XawVendorShellExtPart*); +static XawIcTableList CreateIcTable(Widget, XawVendorShellExtPart*); +static XawIcTableList CurrentSharedIcTable(XawVendorShellExtPart*); +static void Destroy(Widget, XawVendorShellExtPart*); +static void DestroyAllIM(XawVendorShellExtPart*); +static void DestroyIC(Widget, XawVendorShellExtPart*); +static void FreeAllDataOfVendorShell(XawVendorShellExtPart*, + VendorShellWidget); +static XawVendorShellExtPart *GetExtPart(VendorShellWidget); +static XawIcTableList GetIcTable(Widget, XawVendorShellExtPart*); +static XawIcTableList GetIcTableShared(Widget, XawVendorShellExtPart*); +static XIMStyle GetInputStyleOfIC(XawVendorShellExtPart*); +static Bool Initialize(VendorShellWidget, XawVendorShellExtPart*); +static Bool IsCreatedIC(Widget, XawVendorShellExtPart*); +static Bool IsRegistered(Widget, XawVendorShellExtPart*); +static Bool IsSharedIC(XawVendorShellExtPart*); +static Bool NoRegistered(XawVendorShellExtPart*); +static void OpenIM(XawVendorShellExtPart*); +static void Reconnect(XawVendorShellExtPart*); +static void Register(Widget, XawVendorShellExtPart*); +static Bool RegisterToVendorShell(Widget, XawVendorShellExtPart*); +static void ResizeVendorShell(VendorShellWidget, XawVendorShellExtPart*); +static Bool ResizeVendorShell_Core(VendorShellWidget, XawVendorShellExtPart*, + XawIcTableList); +static VendorShellWidget SearchVendorShell(Widget); +static Widget SetErrCnxt(Widget, XIM); +static XawVendorShellExtPart *SetExtPart(VendorShellWidget, + XawVendorShellExtWidget); +static void SetFocus(Widget, XawVendorShellExtPart*); +static void SetFocusValues(Widget, ArgList, Cardinal, Bool); +static void SetICFocus(Widget, XawVendorShellExtPart*); +static void SetICValues(Widget, XawVendorShellExtPart*, Bool); +static void SetICValuesShared(Widget, XawVendorShellExtPart*, XawIcTableList, + Bool); +static void SetValues(Widget, XawVendorShellExtPart*, ArgList, Cardinal); +static unsigned int SetVendorShellHeight(XawVendorShellExtPart*, + unsigned int); +static void SharedICChangeFocusWindow(Widget, XawVendorShellExtPart*, + XawIcTableList); +static void SizeNegotiation(XawIcTableList, unsigned int, unsigned int); +static void Unregister(Widget, XawVendorShellExtPart*); +static void UnregisterFromVendorShell(Widget, XawVendorShellExtPart*); +static void UnsetFocus(Widget); +static void UnsetICFocus(Widget, XawVendorShellExtPart*); +static void VendorShellDestroyed(Widget, XtPointer, XtPointer); + +/* + * From Vendor.c + */ +void XawVendorShellExtResize(Widget); +void XawVendorStructureNotifyHandler(Widget, XtPointer, XEvent*, Boolean*); + + +/* + * From Xt/Resources.c + */ +void _XtCopyFromArg(XtArgVal src, char*, unsigned int); + +static XtResource resources[] = +{ + { + XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet), + Offset (font_set), XtRString, XtDefaultFontSet + }, + { + XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + Offset (foreground), XtRString, (XtPointer)"XtDefaultForeground" + }, + { + XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), + Offset (background), XtRString, (XtPointer)"XtDefaultBackground" + }, + { + XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap), + Offset (bg_pixmap), XtRImmediate, (XtPointer) XtUnspecifiedPixmap + }, + { + XtNinsertPosition, XtCTextPosition, XtRInt, sizeof (XawTextPosition), + Offset (cursor_position), XtRImmediate, (XtPointer) 0 + } +}; +#undef Offset + + +static VendorShellWidget SearchVendorShell(Widget w) +{ + while(w && !XtIsShell(w)) w = XtParent(w); + if (w && XtIsVendorShell(w)) return((VendorShellWidget)w); + return(NULL); +} + +static XContext extContext = (XContext)0; + +static XawVendorShellExtPart * +SetExtPart(VendorShellWidget w, XawVendorShellExtWidget vew) +{ + contextDataRec *contextData; + + if (extContext == (XContext)0) extContext = XUniqueContext(); + + contextData = XtNew(contextDataRec); + contextData->parent = (Widget)w; + contextData->ve = (Widget)vew; + if (XSaveContext(XtDisplay(w), (Window)w, extContext, (char *)contextData)) { + return(NULL); + } + return(&(vew->vendor_ext)); +} + +static XawVendorShellExtPart * +GetExtPart(VendorShellWidget w) +{ + contextDataRec *contextData; + XawVendorShellExtWidget vew; + + if (XFindContext(XtDisplay(w), (Window)w, extContext, + (XPointer*)&contextData)) { + return(NULL); + } + vew = (XawVendorShellExtWidget)contextData->ve; + return(&(vew->vendor_ext)); +} + +static Bool +IsSharedIC(XawVendorShellExtPart * ve) +{ + return( ve->ic.shared_ic ); +} + +static XawIcTableList +GetIcTableShared(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList p; + + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->widget == w) { + if (IsSharedIC(ve)) { + return(ve->ic.shared_ic_table); + } else { + return(p); + } + } + } + return(NULL); +} + +static XawIcTableList +GetIcTable(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList p; + + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->widget == w) { + return(p); + } + } + return(NULL); +} + +static XIMStyle +GetInputStyleOfIC(XawVendorShellExtPart *ve) +{ + + if (!ve) return((XIMStyle)0); + return(ve->ic.input_style); +} + +/*ARGSUSED*/ +static void +ConfigureCB(Widget w, XtPointer closure, XEvent *event, Boolean *unused) +{ + XawIcTableList p; + XawVendorShellExtPart *ve; + VendorShellWidget vw; + XVaNestedList pe_attr; + XRectangle pe_area; + XawTextMargin *margin; + + if (event->type != ConfigureNotify) return; + + if ((vw = SearchVendorShell(w)) == NULL) return; + + if ((ve = GetExtPart(vw)) != NULL) { + if (IsSharedIC(ve)) return; + if ((ve->im.xim == NULL) || + ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL) || !(p->input_style & XIMPreeditPosition)) return; + pe_area.x = 0; + pe_area.y = 0; + pe_area.width = w->core.width; + pe_area.height = w->core.height; + margin = &(((TextWidget)w)->text.margin); + pe_area.x += margin->left; + pe_area.y += margin->top; + pe_area.width -= (margin->left + margin->right - 1); + pe_area.height -= (margin->top + margin->bottom - 1); + + pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL); + XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL); + XtFree(pe_attr); + } +} + +static XContext errContext = (XContext)0; + +static Widget SetErrCnxt(Widget w, XIM xim) +{ + contextErrDataRec *contextErrData; + + if (errContext == (XContext)0) errContext = XUniqueContext(); + + contextErrData = XtNew(contextErrDataRec); + contextErrData->widget = w; + contextErrData->xim = xim; + if (XSaveContext(XtDisplay(w), (Window)xim, errContext, + (char *)contextErrData)) { + return(NULL); + } + return(contextErrData->widget); +} + +#if 0 +static Widget +GetErrCnxt(XIM error_im) +{ + contextErrDataRec *contextErrData; + + if (XFindContext(XDisplayOfIM(error_im), (Window)error_im, errContext, + (XPointer*)&contextErrData)) { + return(NULL); + } + return(contextErrData->widget); +} +#endif + +static void +CloseIM(XawVendorShellExtPart *ve) +{ + if (ve->im.xim) + XCloseIM(ve->im.xim); +} + +static unsigned int +SetVendorShellHeight(XawVendorShellExtPart* ve, unsigned int height) +{ + Arg args[2]; + Cardinal i = 0; + + if (ve->im.area_height < height || height == 0) { + XtSetArg(args[i], XtNheight, + (ve->parent->core.height + height - ve->im.area_height)); + ve->im.area_height = height; + XtSetValues(ve->parent, args, 1); + } + return(ve->im.area_height); +} + +static void +DestroyAllIM(XawVendorShellExtPart *ve) +{ + XawIcTableList p; + contextErrDataRec *contextErrData; + + /* + * Destory all ICs + */ + if (IsSharedIC(ve)) { + if ((p = ve->ic.shared_ic_table) && p->xic) { + DestroyIC(p->widget, ve); + p->xic = NULL; + p->ic_focused = FALSE; + } + } else { + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->xic == NULL) continue; + DestroyIC(p->widget, ve); + p->xic = NULL; + p->ic_focused = FALSE; + } + } + if (!ve->im.xim) return; + /* + * Close Input Method + */ + if (!XFindContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext, + (XPointer*)&contextErrData)) { + if (contextErrData) XtFree((char *)contextErrData); + } + XDeleteContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext); + CloseIM(ve); + ve->im.xim = NULL; + + /* + * resize vendor shell to core size + */ + (void) SetVendorShellHeight(ve, 0); + /* + XawVendorShellExtResize(vw); + */ + return; +} + +static void +FreeAllDataOfVendorShell(XawVendorShellExtPart *ve, VendorShellWidget vw) +{ + XawIcTableList p, next; + contextErrDataRec *contextErrData; + + if (!XFindContext(XtDisplay(vw), (Window)vw, extContext, + (XPointer*)&contextErrData)) { + if (contextErrData) XtFree((char *)contextErrData); + } + XDeleteContext(XtDisplay(vw), (Window)vw, extContext); + if (ve->ic.shared_ic_table) + XtFree((char *)ve->ic.shared_ic_table); + if (ve->im.resources) XtFree((char *)ve->im.resources); + for (p = ve->ic.ic_table; p; p = next) { + next = p->next; + XtFree((char *)p); + } +} + +static void +VendorShellDestroyed(Widget w, XtPointer cl_data, XtPointer ca_data) +{ + XawVendorShellExtPart *ve; + + if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) == NULL ) return; + DestroyAllIM( ve ); + FreeAllDataOfVendorShell( ve, (VendorShellWidget) w ); + return; +} + +#if 0 +static int +IOErrorHandler(XIM error_im) +{ + VendorShellWidget vw; + XawVendorShellExtPart * ve; + + if ((vw = (VendorShellWidget)GetErrCnxt(error_im)) == NULL + || (ve = GetExtPart(vw)) == NULL) return(0); + + DestroyAllIM(ve); + return(0); +} +#endif + +/* + * Attempt to open an input method + */ + +static void +OpenIM(XawVendorShellExtPart *ve) +{ + int i; + char *p, *s, *ns, *end, *pbuf, buf[32]; + XIM xim = NULL; + XIMStyles *xim_styles; + XIMStyle input_style = 0; + Boolean found; + + if (ve->im.open_im == False) return; + ve->im.xim = NULL; + if (ve->im.input_method == NULL) { + if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p) + xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL); + } else { + /* no fragment can be longer than the whole string */ + Cardinal len = strlen (ve->im.input_method) + 5; + + if (len < sizeof buf) pbuf = buf; + else pbuf = XtMalloc (len); + + if (pbuf == NULL) return; + + for(ns=s=ve->im.input_method; ns && *s;) { + /* skip any leading blanks */ + while (*s && isspace(*s)) s++; + if (!*s) break; + if ((ns = end = strchr(s, ',')) == NULL) + end = s + strlen(s); + /* If there is a spurious comma end can be the same as s */ + if (end > s) { + /* strip any trailing blanks */ + while (isspace(*(end - 1))) end--; + + strcpy (pbuf, "@im="); + strncat (pbuf, s, end - s); + pbuf[end - s + 4] = '\0'; + } + + if ((p = XSetLocaleModifiers(pbuf)) != NULL && *p + && (xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL)) != NULL) + break; + + s = ns + 1; + } + + if (pbuf != buf) XtFree (pbuf); + } + if (xim == NULL) { + if ((p = XSetLocaleModifiers("")) != NULL) { + xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL); + } + } + if (xim == NULL) { + XtAppWarning(XtWidgetToApplicationContext(ve->parent), + "Input Method Open Failed"); + return; + } + if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) + || !xim_styles) { + XtAppWarning(XtWidgetToApplicationContext(ve->parent), + "input method doesn't support any style"); + XCloseIM(xim); + return; + } + found = False; + for(ns = s = ve->im.preedit_type; s && !found;) { + while (*s && isspace(*s)) s++; + if (!*s) break; + if ((ns = end = strchr(s, ',')) == NULL) + end = s + strlen(s); + else + ns++; + if (end > s) + while (isspace(*(end - 1))) end--; + + if (!strncmp(s, "OverTheSpot", end - s)) { + input_style = (XIMPreeditPosition | XIMStatusArea); + } else if (!strncmp(s, "OffTheSpot", end - s)) { + input_style = (XIMPreeditArea | XIMStatusArea); + } else if (!strncmp(s, "Root", end - s)) { + input_style = (XIMPreeditNothing | XIMStatusNothing); + } + for (i = 0; (unsigned short)i < xim_styles->count_styles; i++) + if (input_style == xim_styles->supported_styles[i]) { + ve->ic.input_style = input_style; + SetErrCnxt(ve->parent, xim); + ve->im.xim = xim; + found = True; + break; + } + + s = ns; + } + XFree(xim_styles); + + if (!found) { + XCloseIM(xim); + XtAppWarning(XtWidgetToApplicationContext(ve->parent), + "input method doesn't support my input style"); + } +} + +static Bool +ResizeVendorShell_Core(VendorShellWidget vw, XawVendorShellExtPart *ve, + XawIcTableList p) +{ + XVaNestedList pe_attr, st_attr; + XRectangle pe_area, st_area; + XRectangle *get_pe_area = NULL, *get_st_area = NULL; + + st_area.width = 0; + if (p->input_style & XIMStatusArea) { + st_attr = XVaCreateNestedList(0, XNArea, &get_st_area, NULL); + XGetICValues(p->xic, XNStatusAttributes, st_attr, NULL); + XFree(st_attr); + if (p->xic == NULL) { + return(FALSE); + } + st_area.x = 0; + st_area.y = vw->core.height - ve->im.area_height; + st_area.width = get_st_area->width; + st_area.height = get_st_area->height; + XFree(get_st_area); + st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL); + XSetICValues(p->xic, XNStatusAttributes, st_attr, NULL); + XFree(st_attr); + if (p->xic == NULL) { + return(FALSE); + } + } + if (p->input_style & XIMPreeditArea) { + pe_attr = XVaCreateNestedList(0, XNArea, &get_pe_area, NULL); + XGetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL); + XFree(pe_attr); + if (p->xic == NULL) { + return(FALSE); + } + pe_area.x = st_area.width; + pe_area.y = vw->core.height - ve->im.area_height; + pe_area.width = vw->core.width; + pe_area.height = get_pe_area->height; + if (p->input_style & XIMStatusArea) { + pe_area.width -= st_area.width; + } + XFree(get_pe_area); + pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL); + XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL); + XFree(pe_attr); + } + return(TRUE); +} + +static void +ResizeVendorShell(VendorShellWidget vw, XawVendorShellExtPart *ve) +{ + XawIcTableList p; + + if (IsSharedIC(ve)) { + p = ve->ic.shared_ic_table; + if (p->xic == NULL) return; + ResizeVendorShell_Core(vw, ve, p); + return; + } + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->xic == NULL) continue; + if (ResizeVendorShell_Core(vw, ve, p) == FALSE) return; + } +} + +static XawIcTableList +CreateIcTable(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList table; + + table = (XawIcTableList) XtMalloc(sizeof(XawIcTablePart)); + if (table == NULL) return(NULL); + table->widget = w; + table->xic = NULL; + table->flg = table->prev_flg = 0; + table->font_set = NULL; + table->foreground = table->background = 0xffffffff; + table->bg_pixmap = 0; + table->cursor_position = 0xffff; + table->line_spacing = 0; + table->ic_focused = FALSE; + table->openic_error = FALSE; + return(table); +} + +static Bool +RegisterToVendorShell(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList table; + + if ((table = CreateIcTable(w, ve)) == NULL) return(FALSE); + table->next = ve->ic.ic_table; + ve->ic.ic_table = table; + return(TRUE); +} + +static void +UnregisterFromVendorShell(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList *prev, p; + + for (prev = &ve->ic.ic_table; (p = *prev) != NULL; prev = &p->next) { + if (p->widget == w) { + *prev = p->next; + XtFree((char *)p); + break; + } + } + return; +} + +static void +SetICValuesShared(Widget w, XawVendorShellExtPart *ve, + XawIcTableList p, Bool check) +{ + XawIcTableList pp; + + if ((pp = GetIcTable(w, ve)) == NULL) return; + if (check == TRUE && CurrentSharedIcTable(ve) != pp) return; + + if (pp->prev_flg & CICursorP && p->cursor_position != pp->cursor_position) { + p->cursor_position = pp->cursor_position; + p->flg |= CICursorP; + } + if (pp->prev_flg & CIFontSet && p->font_set != pp->font_set) { + p->font_set = pp->font_set; + p->flg |= (CIFontSet|CICursorP); + } + if (pp->prev_flg & CIFg && p->foreground != pp->foreground) { + p->foreground = pp->foreground; + p->flg |= CIFg; + } + if (pp->prev_flg & CIBg && p->background != pp->background) { + p->background = pp->background; + p->flg |= CIBg; + } + if (pp->prev_flg & CIBgPixmap && p->bg_pixmap != pp->bg_pixmap) { + p->bg_pixmap = pp->bg_pixmap; + p->flg |= CIBgPixmap; + } + if (pp->prev_flg & CILineS && p->line_spacing != pp->line_spacing) { + p->line_spacing = pp->line_spacing; + p->flg |= CILineS; + } +} + +static Bool +IsCreatedIC(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList p; + + if (ve->im.xim == NULL) return(FALSE); + if ((p = GetIcTableShared(w, ve)) == NULL) return(FALSE); + if (p->xic == NULL) return(FALSE); + return(TRUE); +} + +static void +SizeNegotiation(XawIcTableList p, unsigned int width, unsigned int height) +{ + XRectangle pe_area, st_area; + XVaNestedList pe_attr = NULL, st_attr = NULL; + int ic_cnt = 0; + XRectangle *pe_area_needed = NULL, *st_area_needed = NULL; + XPointer ic_a[5]; + + if (p->input_style & XIMPreeditArea) { + pe_attr = XVaCreateNestedList(0, XNAreaNeeded, &pe_area_needed, NULL); + ic_a[ic_cnt] = (XPointer) XNPreeditAttributes; ic_cnt++; + ic_a[ic_cnt] = (XPointer) pe_attr; ic_cnt++; + } + if (p->input_style & XIMStatusArea) { + st_attr = XVaCreateNestedList(0, XNAreaNeeded, &st_area_needed, NULL); + ic_a[ic_cnt] = (XPointer) XNStatusAttributes; ic_cnt++; + ic_a[ic_cnt] = (XPointer) st_attr; ic_cnt++; + } + ic_a[ic_cnt] = (XPointer) NULL; + + if (ic_cnt > 0) { + XGetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], NULL); + if (pe_attr) XFree(pe_attr); + if (st_attr) XFree(st_attr); + if (p->xic == NULL) { + p->openic_error = True; + return; + } + pe_attr = st_attr = NULL; + ic_cnt = 0; + if (p->input_style & XIMStatusArea) { + st_area.height = st_area_needed->height; + st_area.x = 0; + st_area.y = height - st_area.height; + if (p->input_style & XIMPreeditArea) { + st_area.width = st_area_needed->width; + } else { + st_area.width = width; + } + + XFree(st_area_needed); + st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL); + ic_a[ic_cnt] = (XPointer) XNStatusAttributes; ic_cnt++; + ic_a[ic_cnt] = (XPointer) st_attr; ic_cnt++; + } + if (p->input_style & XIMPreeditArea) { + if (p->input_style & XIMStatusArea) { + pe_area.x = st_area.width; + pe_area.width = width - st_area.width; + } else { + pe_area.x = 0; + pe_area.width = width; + } + pe_area.height = pe_area_needed->height; + XFree(pe_area_needed); + pe_area.y = height - pe_area.height; + pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL); + ic_a[ic_cnt] = (XPointer) XNPreeditAttributes; ic_cnt++; + ic_a[ic_cnt] = (XPointer) pe_attr; ic_cnt++; + } + ic_a[ic_cnt] = (XPointer) NULL; + XSetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], NULL); + if (pe_attr) XFree(pe_attr); + if (st_attr) XFree(st_attr); + if (p->xic == NULL) { + p->openic_error = True; + return; + } + } +} + +static void +CreateIC(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList p; + XPoint position; + XRectangle pe_area, st_area; + XVaNestedList pe_attr = NULL, st_attr = NULL; + XPointer ic_a[20], pe_a[20], st_a[20]; + Dimension height = 0; + int ic_cnt = 0, pe_cnt = 0, st_cnt = 0; + XawTextMargin *margin; + + if (!XtIsRealized(w)) return; + if (((ve->im.xim == NULL) || (p = GetIcTableShared(w, ve)) == NULL) || + p->xic || (p->openic_error != FALSE)) return; + + p->input_style = GetInputStyleOfIC(ve); + + if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, FALSE); + XFlush(XtDisplay(w)); + + if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) { + if (p->flg & CIFontSet) { + pe_a[pe_cnt] = (XPointer) XNFontSet; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->font_set; pe_cnt++; + st_a[st_cnt] = (XPointer) XNFontSet; st_cnt++; + st_a[st_cnt] = (XPointer) p->font_set; st_cnt++; + if (p->font_set) { + height = maxAscentOfFontSet(p->font_set) + + maxDescentOfFontSet(p->font_set); + } + height = SetVendorShellHeight(ve, height); + } + if (p->flg & CIFg) { + pe_a[pe_cnt] = (XPointer) XNForeground; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->foreground; pe_cnt++; + st_a[st_cnt] = (XPointer) XNForeground; st_cnt++; + st_a[st_cnt] = (XPointer) p->foreground; st_cnt++; + } + if (p->flg & CIBg) { + pe_a[pe_cnt] = (XPointer) XNBackground; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->background; pe_cnt++; + st_a[st_cnt] = (XPointer) XNBackground; st_cnt++; + st_a[st_cnt] = (XPointer) p->background; st_cnt++; + } + if (p->flg & CIBgPixmap) { + pe_a[pe_cnt] = (XPointer) XNBackgroundPixmap; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->bg_pixmap; pe_cnt++; + st_a[st_cnt] = (XPointer) XNBackgroundPixmap; st_cnt++; + st_a[st_cnt] = (XPointer) p->bg_pixmap; st_cnt++; + } + if (p->flg & CILineS) { + pe_a[pe_cnt] = (XPointer) XNLineSpace; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->line_spacing; pe_cnt++; + st_a[st_cnt] = (XPointer) XNLineSpace; st_cnt++; + st_a[st_cnt] = (XPointer) p->line_spacing; st_cnt++; + } + } + if (p->input_style & XIMPreeditArea) { + pe_area.x = 0; + pe_area.y = ve->parent->core.height - height; + pe_area.width = ve->parent->core.width; + pe_area.height = height; + pe_a[pe_cnt] = (XPointer) XNArea; pe_cnt++; + pe_a[pe_cnt] = (XPointer) &pe_area; pe_cnt++; + } + if (p->input_style & XIMPreeditPosition) { + pe_area.x = 0; + pe_area.y = 0; + pe_area.width = w->core.width; + pe_area.height = w->core.height; + margin = &(((TextWidget)w)->text.margin); + pe_area.x += margin->left; + pe_area.y += margin->top; + pe_area.width -= (margin->left + margin->right - 1); + pe_area.height -= (margin->top + margin->bottom - 1); + pe_a[pe_cnt] = (XPointer) XNArea; pe_cnt++; + pe_a[pe_cnt] = (XPointer) &pe_area; pe_cnt++; + if (p->flg & CICursorP) { + _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y); + } else { + position.x = position.y = 0; + } + pe_a[pe_cnt] = (XPointer) XNSpotLocation; pe_cnt++; + pe_a[pe_cnt] = (XPointer) &position; pe_cnt++; + } + if (p->input_style & XIMStatusArea) { + st_area.x = 0; + st_area.y = ve->parent->core.height - height; + st_area.width = ve->parent->core.width; + st_area.height = height; + st_a[st_cnt] = (XPointer) XNArea; st_cnt++; + st_a[st_cnt] = (XPointer) &st_area; st_cnt++; + } + + ic_a[ic_cnt] = (XPointer) XNInputStyle; ic_cnt++; + ic_a[ic_cnt] = (XPointer) p->input_style; ic_cnt++; + ic_a[ic_cnt] = (XPointer) XNClientWindow; ic_cnt++; + ic_a[ic_cnt] = (XPointer) XtWindow(ve->parent); ic_cnt++; + ic_a[ic_cnt] = (XPointer) XNFocusWindow; ic_cnt++; + ic_a[ic_cnt] = (XPointer) XtWindow(w); ic_cnt++; + + if (pe_cnt > 0) { + pe_a[pe_cnt] = (XPointer) NULL; + pe_attr = XVaCreateNestedList(0, pe_a[0], pe_a[1], pe_a[2], pe_a[3], + pe_a[4], pe_a[5], pe_a[6], pe_a[7], pe_a[8], + pe_a[9], pe_a[10], pe_a[11], pe_a[12], + pe_a[13], pe_a[14], pe_a[15], pe_a[16], + pe_a[17], pe_a[18], NULL); + ic_a[ic_cnt] = (XPointer) XNPreeditAttributes; ic_cnt++; + ic_a[ic_cnt] = (XPointer) pe_attr; ic_cnt++; + } + + if (st_cnt > 0) { + st_a[st_cnt] = (XPointer) NULL; + st_attr = XVaCreateNestedList(0, st_a[0], st_a[1], st_a[2], st_a[3], + st_a[4], st_a[5], st_a[6], st_a[7], st_a[8], + st_a[9], st_a[10], st_a[11], st_a[12], + st_a[13], st_a[14], st_a[15], st_a[16], + st_a[17], st_a[18], NULL); + ic_a[ic_cnt] = (XPointer) XNStatusAttributes; ic_cnt++; + ic_a[ic_cnt] = (XPointer) st_attr; ic_cnt++; + } + ic_a[ic_cnt] = (XPointer) NULL; + + p->xic = XCreateIC(ve->im.xim, ic_a[0], ic_a[1], ic_a[2], ic_a[3], + ic_a[4], ic_a[5], ic_a[6], ic_a[7], ic_a[8], ic_a[9], + ic_a[10], ic_a[11], ic_a[12], ic_a[13], ic_a[14], + ic_a[15], ic_a[16], ic_a[17], ic_a[18], NULL); + if (pe_attr) XtFree(pe_attr); + if (st_attr) XtFree(st_attr); + + if (p->xic == NULL) { + p->openic_error = True; + return; + } + + SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height); + + p->flg &= ~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS); + + if (!IsSharedIC(ve)) { + if (p->input_style & XIMPreeditPosition) { + XtAddEventHandler(w, (EventMask)StructureNotifyMask, FALSE, + (XtEventHandler)ConfigureCB, (Opaque)NULL); + } + } +} + +static void +SetICValues(Widget w, XawVendorShellExtPart *ve, Bool focus) +{ + XawIcTableList p; + XPoint position; + XRectangle pe_area; + XVaNestedList pe_attr = NULL, st_attr = NULL; + XPointer ic_a[20], pe_a[20], st_a[20]; + int ic_cnt = 0, pe_cnt = 0, st_cnt = 0; + XawTextMargin *margin; + int height = 0; + + if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL)) return; + + if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, TRUE); + XFlush(XtDisplay(w)); + if (focus == FALSE && + !(p->flg & (CIFontSet | CIFg | CIBg | + CIBgPixmap | CICursorP | CILineS))) return; +#ifdef SPOT + if ((p->input_style & XIMPreeditPosition) + && ((!IsSharedIC(ve) && ((p->flg & ~CIICFocus) == CICursorP)) + || (IsSharedIC(ve) && p->flg == CICursorP))) { + _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y); + _XipChangeSpot(p->xic, position.x, position.y); + p->flg &= ~CICursorP; + return; + } +#endif + + if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) { + if (p->flg & CIFontSet) { + pe_a[pe_cnt] = (XPointer) XNFontSet; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->font_set; pe_cnt++; + st_a[st_cnt] = (XPointer) XNFontSet; st_cnt++; + st_a[st_cnt] = (XPointer) p->font_set; st_cnt++; + if (p->font_set) { + height = maxAscentOfFontSet(p->font_set) + + maxDescentOfFontSet(p->font_set); + } + height = SetVendorShellHeight(ve, height); + } + if (p->flg & CIFg) { + pe_a[pe_cnt] = (XPointer) XNForeground; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->foreground; pe_cnt++; + st_a[st_cnt] = (XPointer) XNForeground; st_cnt++; + st_a[st_cnt] = (XPointer) p->foreground; st_cnt++; + } + if (p->flg & CIBg) { + pe_a[pe_cnt] = (XPointer) XNBackground; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->background; pe_cnt++; + st_a[st_cnt] = (XPointer) XNBackground; st_cnt++; + st_a[st_cnt] = (XPointer) p->background; st_cnt++; + } + if (p->flg & CIBgPixmap) { + pe_a[pe_cnt] = (XPointer) XNBackgroundPixmap; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->bg_pixmap; pe_cnt++; + st_a[st_cnt] = (XPointer) XNBackgroundPixmap; st_cnt++; + st_a[st_cnt] = (XPointer) p->bg_pixmap; st_cnt++; + } + if (p->flg & CILineS) { + pe_a[pe_cnt] = (XPointer) XNLineSpace; pe_cnt++; + pe_a[pe_cnt] = (XPointer) p->line_spacing; pe_cnt++; + st_a[st_cnt] = (XPointer) XNLineSpace; st_cnt++; + st_a[st_cnt] = (XPointer) p->line_spacing; st_cnt++; + } + } + if (p->input_style & XIMPreeditPosition) { + if (p->flg & CICursorP) { + _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y); + pe_a[pe_cnt] = (XPointer) XNSpotLocation; pe_cnt++; + pe_a[pe_cnt] = (XPointer) &position; pe_cnt++; + } + } + if (IsSharedIC(ve)) { + if (p->input_style & XIMPreeditPosition) { + pe_area.x = 0; + pe_area.y = 0; + pe_area.width = w->core.width; + pe_area.height = w->core.height; + margin = &(((TextWidget)w)->text.margin); + pe_area.x += margin->left; + pe_area.y += margin->top; + pe_area.width -= (margin->left + margin->right - 1); + pe_area.height -= (margin->top + margin->bottom - 1); + pe_a[pe_cnt] = (XPointer) XNArea; pe_cnt++; + pe_a[pe_cnt] = (XPointer) &pe_area; pe_cnt++; + } + } + + if (pe_cnt > 0) { + pe_a[pe_cnt] = (XPointer) NULL; + pe_attr = XVaCreateNestedList(0, pe_a[0], pe_a[1], pe_a[2], pe_a[3], + pe_a[4], pe_a[5], pe_a[6], pe_a[7], + pe_a[8], pe_a[9], pe_a[10], pe_a[11], + pe_a[12], pe_a[13], pe_a[14], pe_a[15], + pe_a[16], pe_a[17], pe_a[18], NULL); + ic_a[ic_cnt] = (XPointer) XNPreeditAttributes; ic_cnt++; + ic_a[ic_cnt] = (XPointer) pe_attr; ic_cnt++; + } + if (st_cnt > 0) { + st_a[st_cnt] = (XPointer) NULL; + st_attr = XVaCreateNestedList(0, st_a[0], st_a[1], st_a[2], st_a[3], + st_a[4], st_a[5], st_a[6], st_a[7], + st_a[8], st_a[9], st_a[10], st_a[11], + st_a[12], st_a[13], st_a[14], st_a[15], + st_a[16], st_a[17], st_a[18], NULL); + ic_a[ic_cnt] = (XPointer) XNStatusAttributes; ic_cnt++; + ic_a[ic_cnt] = (XPointer) st_attr; ic_cnt++; + } + if (focus == TRUE) { + ic_a[ic_cnt] = (XPointer) XNFocusWindow; ic_cnt++; + ic_a[ic_cnt] = (XPointer) XtWindow(w); ic_cnt++; + } + if (ic_cnt > 0) { + ic_a[ic_cnt] = (XPointer) NULL; + XSetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], ic_a[4], + ic_a[5], ic_a[6], ic_a[7], ic_a[8], ic_a[9], ic_a[10], + ic_a[11], ic_a[12], ic_a[13], ic_a[14], ic_a[15], + ic_a[16], ic_a[17], ic_a[18], NULL); + if (pe_attr) XtFree(pe_attr); + if (st_attr) XtFree(st_attr); + } + + if (IsSharedIC(ve) && p->flg & CIFontSet) + SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height); + + p->flg &= ~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS); +} + +static void +SharedICChangeFocusWindow(Widget w, XawVendorShellExtPart *ve, + XawIcTableList p) +{ + XawIcTableList pp; + + if (w == NULL) { + ve->ic.current_ic_table = NULL; + return; + } + if ((pp = GetIcTable(w, ve)) == NULL) return; + ve->ic.current_ic_table = pp; + SetICValues(w, ve, TRUE); +} + +static XawIcTableList +CurrentSharedIcTable(XawVendorShellExtPart *ve) +{ + return(ve->ic.current_ic_table); +} + +static void +SetICFocus(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList p, pp; + + if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL)) return; + + if (IsSharedIC(ve)) { + pp = CurrentSharedIcTable(ve); + if (pp == NULL || pp->widget != w) { + SharedICChangeFocusWindow(w, ve, p); + } + } + if (p->flg & CIICFocus && p->ic_focused == FALSE) { + p->ic_focused = TRUE; + XSetICFocus(p->xic); + } + p->flg &= ~CIICFocus; +} + +static void +UnsetICFocus(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList p, pp; + + if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL)) return; + + if (IsSharedIC(ve) && (pp = CurrentSharedIcTable(ve))) { + if (pp->widget != w) { + return; + } + SharedICChangeFocusWindow(NULL, ve, p); + } + if (p->ic_focused == TRUE) { + XUnsetICFocus(p->xic); + p->ic_focused = FALSE; + } +} + +static void +SetValues(Widget w, XawVendorShellExtPart *ve, + ArgList args, Cardinal num_args) +{ + ArgList arg; + + XrmName argName; + XrmResourceList xrmres; + Cardinal i; + XawIcTablePart *p, save_tbl; + + if ((p = GetIcTable(w, ve)) == NULL) return; + + memcpy(&save_tbl, p, sizeof(XawIcTablePart)); + + for (arg = args ; num_args != 0; num_args--, arg++) { + argName = XrmStringToName(arg->name); + for (xrmres = (XrmResourceList)ve->im.resources, i = 0; + i < ve->im.num_resources; i++, xrmres++) { + if (argName == xrmres->xrm_name) { + _XtCopyFromArg(arg->value, + (char *)p - xrmres->xrm_offset - 1, + xrmres->xrm_size); + break; + } + } + } + if (p->font_set != save_tbl.font_set) { + p->flg |= CIFontSet; + } + if (p->foreground != save_tbl.foreground) { + p->flg |= CIFg; + } + if (p->background !=save_tbl.background) { + p->flg |= CIBg; + } + if (p->bg_pixmap != save_tbl.bg_pixmap) { + p->flg |= CIBgPixmap; + } + if (p->cursor_position != save_tbl.cursor_position) { + p->flg |= CICursorP; + } + if (p->line_spacing != save_tbl.line_spacing) { + p->flg |= CILineS; + } + p->prev_flg |= p->flg; +} + +static void +SetFocus(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList p; + if ((p = GetIcTableShared(w, ve)) == NULL) return; + + if ( p->ic_focused == FALSE || IsSharedIC(ve)) { + p->flg |= CIICFocus; + } + p->prev_flg |= p->flg; +} + +static void +DestroyIC(Widget w, XawVendorShellExtPart *ve) +{ + XawIcTableList p; + + if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL)) return; + if (IsSharedIC(ve)) { + if (GetIcTable(w, ve) == ve->ic.current_ic_table) { + UnsetICFocus(w, ve); + } + return; + } + XDestroyIC(p->xic); + if (!IsSharedIC(ve)) { + if (p->input_style & XIMPreeditPosition) { + XtRemoveEventHandler(w, (EventMask)StructureNotifyMask, FALSE, + (XtEventHandler)ConfigureCB, (Opaque)NULL); + } + } +} + +static void +SetFocusValues(Widget inwidg, ArgList args, Cardinal num_args, Bool focus) +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if ((ve = GetExtPart(vw)) != NULL) { + if (num_args > 0) SetValues(inwidg, ve, args, num_args); + if (focus) SetFocus(inwidg, ve); + if (XtIsRealized((Widget)vw) && ve->im.xim) { + if (IsCreatedIC(inwidg, ve)) { + SetICValues(inwidg, ve, FALSE); + if (focus) SetICFocus(inwidg, ve); + } else { + CreateIC(inwidg, ve); + SetICFocus(inwidg, ve); + } + } + } +} + +static void +UnsetFocus(Widget inwidg) +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + XawIcTableList p; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if ((ve = GetExtPart(vw)) != NULL) { + if ((p = GetIcTableShared(inwidg, ve)) == NULL) return; + if (p->flg & CIICFocus) { + p->flg &= ~CIICFocus; + } + p->prev_flg &= ~CIICFocus; + if (ve->im.xim && XtIsRealized((Widget)vw) && p->xic) { + UnsetICFocus(inwidg, ve); + } + } +} + +static Bool +IsRegistered(Widget w, XawVendorShellExtPart* ve) +{ + XawIcTableList p; + + for (p = ve->ic.ic_table; p; p = p->next) + { + if (p->widget == w) return(TRUE); + } + return(FALSE); +} + +static void +Register(Widget inwidg, XawVendorShellExtPart* ve) +{ + if (ve->im.xim == NULL) + { + OpenIM(ve); + } + + if (IsRegistered(inwidg, ve)) return; + + if (RegisterToVendorShell(inwidg, ve) == FALSE) return; + + if (ve->im.xim == NULL) return; + + if (XtIsRealized(ve->parent)) + { + CreateIC(inwidg, ve); + SetICFocus(inwidg, ve); + } +} + +static Bool +NoRegistered(XawVendorShellExtPart* ve) +{ + if (ve->ic.ic_table == NULL) return(TRUE); + return(FALSE); +} + +static void +Unregister(Widget inwidg, XawVendorShellExtPart *ve) +{ + if (!IsRegistered(inwidg, ve)) return; + + DestroyIC(inwidg, ve); + + UnregisterFromVendorShell(inwidg, ve); + + if (NoRegistered(ve)) + { + CloseIM(ve); + ve->im.xim = NULL; + /* + * resize vendor shell to core size + */ + (void) SetVendorShellHeight(ve, 0); + } +} + +static void +AllCreateIC(XawVendorShellExtPart *ve) +{ + XawIcTableList p; + + if (ve->im.xim == NULL) return; + if (IsSharedIC(ve) && ve->ic.ic_table[0].widget) { + p = ve->ic.shared_ic_table; + if (p->xic == NULL) + CreateIC(ve->ic.ic_table[0].widget, ve); + SetICFocus(ve->ic.ic_table[0].widget, ve); + return; + } + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->xic == NULL) + CreateIC(p->widget, ve); + } + for (p = ve->ic.ic_table; p; p = p->next) { + SetICFocus(p->widget, ve); + } +} + + +static void +Reconnect(XawVendorShellExtPart *ve) +{ + XawIcTableList p; + + ve->im.open_im = True; + if (ve->im.xim == NULL) { + OpenIM(ve); + } + if (ve->im.xim == NULL) return; + + if (IsSharedIC(ve)) { + p = ve->ic.shared_ic_table; + p->flg = p->prev_flg; + p->openic_error = FALSE; + } else { + for (p = ve->ic.ic_table; p; p = p->next) { + p->flg = p->prev_flg; + p->openic_error = FALSE; + } + } + AllCreateIC(ve); +} + + +static void +CompileResourceList(XtResourceList res, unsigned int num_res) +{ + unsigned int count; + +#define xrmres ((XrmResourceList) res) + for (count = 0; count < num_res; res++, count++) { + xrmres->xrm_name = XrmPermStringToQuark(res->resource_name); + xrmres->xrm_class = XrmPermStringToQuark(res->resource_class); + xrmres->xrm_type = XrmPermStringToQuark(res->resource_type); + xrmres->xrm_offset = -res->resource_offset - 1; + xrmres->xrm_default_type = XrmPermStringToQuark(res->default_type); + } +#undef xrmres +} + +static Bool +Initialize(VendorShellWidget vw, XawVendorShellExtPart *ve) +{ + if (!XtIsVendorShell((Widget)vw)) return(FALSE); + ve->parent = (Widget)vw; + ve->im.xim = NULL; + ve->im.area_height = 0; + ve->im.resources = (XrmResourceList)XtMalloc(sizeof(resources)); + if (ve->im.resources == NULL) return(FALSE); + memcpy((char *)ve->im.resources, (char *)resources, sizeof(resources)); + ve->im.num_resources = XtNumber(resources); + CompileResourceList( (XtResourceList) ve->im.resources, + ve->im.num_resources ); + if ((ve->ic.shared_ic_table = CreateIcTable( (Widget)vw, ve)) == NULL) + return(FALSE); + ve->ic.current_ic_table = NULL; + ve->ic.ic_table = NULL; + return(TRUE); +} + + +/* Destroy() + * + * This frees all (most?) of the resources malloced by XawIm. + * It is called by _XawImDestroy, which is called by Vendor.c's + * VendorExt's Destroy method. Sheeran, Omron KK, 93/08/05 */ + +static void +Destroy(Widget w, XawVendorShellExtPart *ve) +{ + contextDataRec *contextData; + contextErrDataRec *contextErrData; + + if (!XtIsVendorShell( w ) ) + return; + XtFree( (char*) ve->im.resources ); + + if (extContext != (XContext)0 && + !XFindContext (XtDisplay (w), (Window)w, + extContext, (XPointer*)&contextData)) + XtFree( (char*) contextData ); + + if (errContext != (XContext)0 && + !XFindContext (XDisplayOfIM( ve->im.xim ), (Window) ve->im.xim, + errContext, (XPointer*) &contextErrData)) + XtFree( (char*) contextErrData ); +} + +/********************************************* + * + * SEMI-PRIVATE FUNCTIONS + * For use by other Xaw modules + * + ********************************************/ + +void +_XawImResizeVendorShell(Widget w) +{ + XawVendorShellExtPart *ve; + + if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) && ve->im.xim ) { + ResizeVendorShell( (VendorShellWidget) w, ve ); + } +} + + +Dimension +_XawImGetShellHeight(Widget w) +{ + XawVendorShellExtPart *ve; + + if (!XtIsVendorShell( w ) ) return( w->core.height ); + if ( (ve = GetExtPart( (VendorShellWidget) w )) != NULL ) { + return( w->core.height - ve->im.area_height ); + } + return( w->core.height ); +} + +void +_XawImRealize(Widget w) +{ + XawVendorShellExtPart *ve; + + if ( !XtIsRealized( w ) || !XtIsVendorShell( w ) ) return; + if ( (ve = GetExtPart( (VendorShellWidget) w )) != NULL ) { + XtAddEventHandler( w, (EventMask)StructureNotifyMask, FALSE, + XawVendorStructureNotifyHandler, (XtPointer)NULL ); + AllCreateIC(ve); + } +} + +void +_XawImInitialize(Widget w, Widget ext) +{ + XawVendorShellExtPart *ve; + + if ( !XtIsVendorShell( w ) ) return; + if ( (ve = SetExtPart( (VendorShellWidget) w, (XawVendorShellExtWidget)ext )) != NULL ) { + if ( Initialize( (VendorShellWidget) w, ve ) == FALSE ) return; + XtAddCallback( w, XtNdestroyCallback, VendorShellDestroyed, + (XtPointer) NULL ); + } +} + +void +_XawImReconnect(Widget inwidg) +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if ((ve = GetExtPart(vw)) != NULL) { + Reconnect(ve); + } +} + +void +_XawImRegister(Widget inwidg) +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if ((ve = GetExtPart(vw)) != NULL) { + Register(inwidg, ve); + } +} + +void +_XawImUnregister(Widget inwidg) +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if ((ve = GetExtPart(vw)) != NULL) { + Unregister(inwidg, ve); + } +} + +void +_XawImSetValues(Widget inwidg, ArgList args, Cardinal num_args) +{ + SetFocusValues( inwidg, args, num_args, FALSE ); +} + +void +_XawImSetFocusValues(Widget inwidg, ArgList args, Cardinal num_args) +{ + SetFocusValues(inwidg, args, num_args, TRUE); +} + +void +_XawImUnsetFocus(Widget inwidg) +{ + UnsetFocus(inwidg); +} + +int +_XawImWcLookupString(Widget inwidg, XKeyPressedEvent *event, + wchar_t* buffer_return, int bytes_buffer, + KeySym *keysym_return) +{ + XawVendorShellExtPart* ve; + VendorShellWidget vw; + XawIcTableList p; + int i, ret; + char tmp_buf[64], *tmp_p; + wchar_t* buf_p; + + if ((vw = SearchVendorShell(inwidg)) && (ve = GetExtPart(vw)) && + ve->im.xim && (p = GetIcTableShared(inwidg, ve)) && p->xic) { + return(XwcLookupString(p->xic, event, buffer_return, bytes_buffer/sizeof(wchar_t), + keysym_return, NULL)); + } + ret = XLookupString( event, tmp_buf, sizeof(tmp_buf), keysym_return, + NULL ); + for ( i = 0, tmp_p = tmp_buf, buf_p = buffer_return; i < ret; i++ ) { + *buf_p++ = _Xaw_atowc(*tmp_p++); + } + return( ret ); +} + +int +_XawLookupString(Widget w, XKeyEvent *event, char *buffer_return, int buffer_size, + KeySym *keysym_return) +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + XawIcTableList p; + + if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw)) + && ve->im.xim && (p = GetIcTableShared(w, ve)) && p->xic) + return (XmbLookupString(p->xic, event, buffer_return, buffer_size, + keysym_return, NULL)); + + return (XLookupString(event, buffer_return, buffer_size, + keysym_return, NULL)); +} + +int +_XawImGetImAreaHeight(Widget w) +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw))) { + return(ve->im.area_height); + } + return(0); +} + +void +_XawImCallVendorShellExtResize(Widget w) +{ + VendorShellWidget vw; + + if ((vw = SearchVendorShell(w)) && GetExtPart(vw)) { + XawVendorShellExtResize((Widget)vw); + } +} + + +/* _XawImDestroy() + * + * This should be called by the VendorExt from its + * core Destroy method. Sheeran, Omron KK 93/08/05 */ + +void +_XawImDestroy(Widget w, Widget ext) +{ + XawVendorShellExtPart *ve; + + if ( !XtIsVendorShell( w ) ) return; + if ( (ve = GetExtPart( (VendorShellWidget) w )) != NULL ) + Destroy( w, ve ); +} diff --git a/src/XawInit.c b/src/XawInit.c new file mode 100644 index 0000000..5ca1ef8 --- /dev/null +++ b/src/XawInit.c @@ -0,0 +1,97 @@ +/* + * +Copyright 1989, 1998 The Open Group +Copyright 2003-2004 Roland Mainz + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * + * XawInitializeWidgetSet + * + * This routine forces a reference to vendor shell so that the one in this + * widget is installed. Any other cross-widget set initialization should be + * done here as well. All Athena widgets should include "XawInit.h" and + * call this routine from their ClassInitialize procs (this routine may be + * used as the class init proc). + */ +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include "Private.h" + +void +XawInitializeWidgetSet(void) +{ + static Boolean firsttime = True; + + if (firsttime) { + firsttime = False; +#ifndef OLDXAW + XawPixmapsInitialize(); + XawInitializeDefaultConverters(); +#endif + XtInitializeWidgetClass(vendorShellWidgetClass); + } +} + +/* XawOpenApplication() - mainly identical to XtOpenApplication() but + * takes a |Display *| and |Screen *| as arguments, too... */ +Widget XawOpenApplication(XtAppContext *app_context_return, + Display *dpy, + Screen *screen, + String application_name, + String application_class, + WidgetClass widget_class, + int *argc, + String *argv) +{ + Widget toplevel; + Cardinal n; + Arg args[2]; + + XtToolkitInitialize(); + *app_context_return = XtCreateApplicationContext(); + if( *app_context_return == NULL ) + return NULL; + + XtDisplayInitialize(*app_context_return, dpy, + application_name, application_class, + NULL, 0, + argc, argv); + + n = 0; + if (screen) { + XtSetArg(args[n], XtNscreen, screen); n++; + } + toplevel = XtAppCreateShell(application_name, + application_class, + widget_class, + dpy, + args, n); + + return toplevel; +} + diff --git a/src/sharedlib.c b/src/sharedlib.c new file mode 100644 index 0000000..e892d82 --- /dev/null +++ b/src/sharedlib.c @@ -0,0 +1,173 @@ +/* + +Copyright 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#if defined(SUNSHLIB) && !defined(SHAREDCODE) + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern AsciiSinkClassRec asciiSinkClassRec; +WidgetClass asciiSinkObjectClass = (WidgetClass)&asciiSinkClassRec; + +extern AsciiSrcClassRec asciiSrcClassRec; +WidgetClass asciiSrcObjectClass = (WidgetClass)&asciiSrcClassRec; + +extern AsciiTextClassRec asciiTextClassRec; +WidgetClass asciiTextWidgetClass = (WidgetClass)&asciiTextClassRec; + +#ifdef ASCII_STRING +extern AsciiStringClassRec asciiStringClassRec; +WidgetClass asciiStringWidgetClass = (WidgetClass)&asciiStringClassRec; +#endif + +#ifdef ASCII_DISK +extern AsciiDiskClassRec asciiDiskClassRec; +WidgetClass asciiDiskWidgetClass = (WidgetClass)&asciiDiskClassRec; +#endif + +extern MultiSinkClassRec multiSinkClassRec; +WidgetClass multiSinkObjectClass = (WidgetClass)&multiSinkClassRec; + +extern MultiSrcClassRec multiSrcClassRec; +WidgetClass multiSrcObjectClass = (WidgetClass)&multiSrcClassRec; + +extern BoxClassRec boxClassRec; +WidgetClass boxWidgetClass = (WidgetClass)&boxClassRec; + +extern CommandClassRec commandClassRec; +WidgetClass commandWidgetClass = (WidgetClass) &commandClassRec; + +extern DialogClassRec dialogClassRec; +WidgetClass dialogWidgetClass = (WidgetClass)&dialogClassRec; + +extern FormClassRec formClassRec; +WidgetClass formWidgetClass = (WidgetClass)&formClassRec; + +extern GripClassRec gripClassRec; +WidgetClass gripWidgetClass = (WidgetClass) &gripClassRec; + +extern LabelClassRec labelClassRec; +WidgetClass labelWidgetClass = (WidgetClass)&labelClassRec; + +extern ListClassRec listClassRec; +WidgetClass listWidgetClass = (WidgetClass)&listClassRec; + +extern MenuButtonClassRec menuButtonClassRec; +WidgetClass menuButtonWidgetClass = (WidgetClass) &menuButtonClassRec; + +extern PanedClassRec panedClassRec; +WidgetClass panedWidgetClass = (WidgetClass) &panedClassRec; +WidgetClass vPanedWidgetClass = (WidgetClass) &panedClassRec; + +extern PannerClassRec pannerClassRec; +WidgetClass pannerWidgetClass = (WidgetClass) &pannerClassRec; + +extern PortholeClassRec portholeClassRec; +WidgetClass portholeWidgetClass = (WidgetClass) &portholeClassRec; + +extern RepeaterClassRec repeaterClassRec; +WidgetClass repeaterWidgetClass = (WidgetClass) &repeaterClassRec; + +extern ScrollbarClassRec scrollbarClassRec; +WidgetClass scrollbarWidgetClass = (WidgetClass)&scrollbarClassRec; + +extern SimpleClassRec simpleClassRec; +WidgetClass simpleWidgetClass = (WidgetClass)&simpleClassRec; + +extern SimpleMenuClassRec simpleMenuClassRec; +WidgetClass simpleMenuWidgetClass = (WidgetClass)&simpleMenuClassRec; + +extern SmeClassRec smeClassRec; +WidgetClass smeObjectClass = (WidgetClass) &smeClassRec; + +extern SmeBSBClassRec smeBSBClassRec; +WidgetClass smeBSBObjectClass = (WidgetClass) &smeBSBClassRec; + +extern SmeLineClassRec smeLineClassRec; +WidgetClass smeLineObjectClass = (WidgetClass) &smeLineClassRec; + +extern StripChartClassRec stripChartClassRec; +WidgetClass stripChartWidgetClass = (WidgetClass) &stripChartClassRec; + +extern TextClassRec textClassRec; +WidgetClass textWidgetClass = (WidgetClass)&textClassRec; + +unsigned long FMT8BIT = 0L; +unsigned long XawFmt8Bit = 0L; +unsigned long XawFmtWide = 0L; + +extern TextSinkClassRec textSinkClassRec; +WidgetClass textSinkObjectClass = (WidgetClass)&textSinkClassRec; + +extern TextSrcClassRec textSrcClassRec; +WidgetClass textSrcObjectClass = (WidgetClass)&textSrcClassRec; + +extern ToggleClassRec toggleClassRec; +WidgetClass toggleWidgetClass = (WidgetClass) &toggleClassRec; + +extern TreeClassRec treeClassRec; +WidgetClass treeWidgetClass = (WidgetClass) &treeClassRec; + +extern VendorShellClassRec vendorShellClassRec; +WidgetClass vendorShellWidgetClass = (WidgetClass) &vendorShellClassRec; + +extern ViewportClassRec viewportClassRec; +WidgetClass viewportWidgetClass = (WidgetClass)&viewportClassRec; + +#endif /* SUNSHLIB */ diff --git a/xaw6.pc.in b/xaw6.pc.in new file mode 100644 index 0000000..cee7220 --- /dev/null +++ b/xaw6.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Xaw +Description: X Athena Widgets Library, version 6 +Version: @PACKAGE_VERSION@ +Requires: xproto xt +Requires.private: x11 xext xt xmu +Cflags: -I${includedir} +Libs: -L${libdir} -lXaw6 diff --git a/xaw7.pc.in b/xaw7.pc.in new file mode 100644 index 0000000..0e55ff9 --- /dev/null +++ b/xaw7.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Xaw +Description: X Athena Widgets Library, version 7 +Version: @PACKAGE_VERSION@ +Requires: xproto xt +Requires.private: x11 xext xt xmu xpm +Cflags: -I${includedir} +Libs: -L${libdir} -lXaw7 -- 2.7.4