Add WINGs tutorial
The original website is http://www.quantitativefinanceservices.com/OpenDir/WINGslib/WINGToc.html and it had the following notice at the bottom: Copyright (c) 2010 Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". So we are fine.
42
WINGs_tutorial/3 Steps to Make a WINGs User Interface.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0074)WINGsIntro.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="keywords" content="WINGs, tutorial, Introduction, C, programming, GUI, Window Maker, Linux">
|
||||
<meta name="description" content="WINGs library tutorial">
|
||||
<meta name="license" content="GNU Free Documentation License">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSITFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGtoc.html">LAST: Contents</a></td><td align="RIGHT"><a href="WINGStep1.html">NEXT: Step 1 Drawing a Window</a></td></tr></tbody></table>
|
||||
|
||||
<h3>Make a WINGs based Graphical User Interface in 3 Steps</h3>
|
||||
|
||||
The WINGs library is the library with routines for a graphical user interface which comes with the Window Maker window manager. In 2010 the library's web page is <a href="http://windowmaker.org/development.php?show=wings">here</a> on the windowmaker.org website. You can download windowmaker with the WINGs libraries <a href="http://windowmaker.org/index.php">here</a>. The library provides widgets which you can use to make a graphical user interface. A widget is a software module which is used to interact with the user. Buttons and menus are widgets. The WINGs library offers the possibility to programme these widgets in a few lines of C code, so that you can dedicate the rest of your time to the functionality in your application.
|
||||
|
||||
<p>This tutorial shows in three simple steps how to write a graphical user interface with WINGs. Those three steps will cover all that is needed to write the major dialogs and widgets needed for communication between application and user. It assumes that you know how to programme in C, but you do not need to know anything about GUI-programming.
|
||||
|
||||
</p><p> Step 1 in this tutorial will show the framework for an application which uses a WINGS graphical user interface. It shows how you have the WINGs library create a widget for you, and how you set its properties. Step 2 briefly explains what events are, and how you make your application react to incoming events. This is what makes your interface work. Step 3 shows how to insert two buttons and a text area into the application's window, and how to implement the handling of events for them. Along the explanations in the main text, there are a few examples of source code. Most WINGs function names speak for themselves, and therefore, not everything in the source code is repeated in the text. You can just read the code. The example developed in the three steps is a sufficient blueprint to allow you to use the other widgets in the WINGs library. To do that, just look up the functions in the relevant section in the library description section.
|
||||
|
||||
</p><p>There are three programming detail sections after the three tutorial sections. They explain how to use Xlib code along with the WINGs code, how to set up a widget in which you can draw OpenGL images, and how to change part of the WINGs library source for your own needs, among other things.
|
||||
|
||||
</p><p>To compile WINGs widgets, you need a C-compiler, the WINGs library, and an X-server on your computer. The first few libraries which you need will be libWINGs and libwraster, and the X11 library libXft. If the WINGs library <em>directory</em> is in the /usr/lib path, and your X11 libraries in /usr/X11/lib, you can compile the code with gcc as follows
|
||||
</p><p><kbd>gcc -x c FileName -lXft -L/usr/X11/lib -L/usr/lib -lwraster -lWINGs -o FileName</kbd>
|
||||
</p><p>This will get you a binary called FileName which you can run, either by double clicking, or by running the <kbd>./FileName</kbd> command in an xterm.
|
||||
</p><p> To compile in C++, just replace the <code> fprintf(stderr, ..)</code> command with an appropriate <code>cerr << </code>, add the namespace command, and replace the <stdio.h> with the iostream header, then compile as
|
||||
<kbd>
|
||||
g++ -x c++ -lXft FileName -L/usr/X11/lib -L/usr/lib -lwraster -lWINGs-o FileName</kbd>
|
||||
|
||||
|
||||
|
||||
</p><p>The function prototypes in the library description were retrieved from the information in the WINGs man pages which were compiled by Alexey Voinov. His page was <a href="http://voins.program.ru/windowmaker/wingsman.html">here</a> in 2010.
|
||||
|
||||
|
||||
<br>
|
||||
<br>
|
||||
</p><p>
|
||||
</p><table align="JUSITFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGtoc.html">LAST: Contents</a></td><td align="RIGHT"><a href="WINGStep1.html">NEXT: Step 1 Drawing a Window</a></td></tr></tbody></table>
|
||||
|
||||
|
||||
|
||||
</body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
70
WINGs_tutorial/EighthWindow.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "editmenu.h"
|
||||
|
||||
#define WINWIDTH 300
|
||||
#define WINHEIGHT 400
|
||||
#define MENUWIDTH 80
|
||||
#define MENITEMHT 21
|
||||
|
||||
struct datacouple{WMWindow *window;
|
||||
WEditMenu *menu;
|
||||
} datacouple;
|
||||
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
WMDestroyWidget(self);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void getMenu(WMWidget *self, void *data){
|
||||
WMPoint position;
|
||||
struct datacouple *tmp=(struct datacouple *)data;
|
||||
if(WMGetButtonSelected(self)){
|
||||
position=WMGetViewScreenPosition(WMWidgetView(tmp->window));
|
||||
WEditMenuShowAt(tmp->menu,(position.x>MENUWIDTH)?position.x-MENUWIDTH:0, position.y+MENITEMHT,tmp->window);
|
||||
}else
|
||||
WEditMenuHide(tmp->menu);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv){
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
WMWindow *win;
|
||||
WEditMenu *submenu, *menu;
|
||||
WEditMenuItem * menuitem;
|
||||
struct datacouple Mainmenu;
|
||||
WMButton *Button;
|
||||
|
||||
WMInitializeApplication("MenuWindow", &argc, argv);
|
||||
display = XOpenDisplay("");
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
win = WMCreateWindow(screen, "Menu");
|
||||
WMResizeWidget(win, WINWIDTH, WINHEIGHT);
|
||||
WMSetWindowCloseAction(win, closeAll, NULL);
|
||||
|
||||
submenu=WCreateEditMenu(screen,"Submenu");
|
||||
menuitem =WAddMenuItemWithTitle(submenu,"Submenu item");
|
||||
menu=WCreateEditMenu(screen,"Main menu");
|
||||
menuitem = WAddMenuItemWithTitle(menu,"To submenu");
|
||||
WSetEditMenuSubmenu(menu, menuitem , submenu);
|
||||
menuitem = WAddMenuItemWithTitle(menu,"Main item");
|
||||
|
||||
Mainmenu.window=win;
|
||||
Mainmenu.menu=menu;
|
||||
|
||||
Button =WMCreateButton(win,WBTPushOnPushOff);
|
||||
WMSetButtonText (Button, "Menu");
|
||||
WMSetButtonAction (Button, getMenu, &Mainmenu);
|
||||
WMMoveWidget(Button, 1,1);
|
||||
|
||||
WMRealizeWidget(win);
|
||||
WMRealizeWidget(Button);
|
||||
WMRealizeWidget(menu);
|
||||
WMRealizeWidget(submenu);
|
||||
|
||||
WMMapSubwidgets(win);
|
||||
WMMapWidget(win);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
370
WINGs_tutorial/FDL.html
Normal file
@@ -0,0 +1,370 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0068)FDL.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface - Licence</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSITFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGtoc.html">Contents</a></td><td></td></tr></tbody></table>
|
||||
|
||||
|
||||
<pre> GNU Free Documentation License
|
||||
Version 1.1, March 2000
|
||||
|
||||
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
0. PREAMBLE
|
||||
|
||||
The purpose of this License is to make a manual, textbook, or other
|
||||
written document "free" in the sense of freedom: to assure everyone
|
||||
the effective freedom to copy and redistribute it, with or without
|
||||
modifying it, either commercially or noncommercially. Secondarily,
|
||||
this License preserves for the author and publisher a way to get
|
||||
credit for their work, while not being considered responsible for
|
||||
modifications made by others.
|
||||
|
||||
This License is a kind of "copyleft", which means that derivative
|
||||
works of the document must themselves be free in the same sense. It
|
||||
complements the GNU General Public License, which is a copyleft
|
||||
license designed for free software.
|
||||
|
||||
We have designed this License in order to use it for manuals for free
|
||||
software, because free software needs free documentation: a free
|
||||
program should come with manuals providing the same freedoms that the
|
||||
software does. But this License is not limited to software manuals;
|
||||
it can be used for any textual work, regardless of subject matter or
|
||||
whether it is published as a printed book. We recommend this License
|
||||
principally for works whose purpose is instruction or reference.
|
||||
|
||||
|
||||
1. APPLICABILITY AND DEFINITIONS
|
||||
|
||||
This License applies to any manual or other work that contains a
|
||||
notice placed by the copyright holder saying it can be distributed
|
||||
under the terms of this License. The "Document", below, refers to any
|
||||
such manual or work. Any member of the public is a licensee, and is
|
||||
addressed as "you".
|
||||
|
||||
A "Modified Version" of the Document means any work containing the
|
||||
Document or a portion of it, either copied verbatim, or with
|
||||
modifications and/or translated into another language.
|
||||
|
||||
A "Secondary Section" is a named appendix or a front-matter section of
|
||||
the Document that deals exclusively with the relationship of the
|
||||
publishers or authors of the Document to the Document's overall subject
|
||||
(or to related matters) and contains nothing that could fall directly
|
||||
within that overall subject. (For example, if the Document is in part a
|
||||
textbook of mathematics, a Secondary Section may not explain any
|
||||
mathematics.) The relationship could be a matter of historical
|
||||
connection with the subject or with related matters, or of legal,
|
||||
commercial, philosophical, ethical or political position regarding
|
||||
them.
|
||||
|
||||
The "Invariant Sections" are certain Secondary Sections whose titles
|
||||
are designated, as being those of Invariant Sections, in the notice
|
||||
that says that the Document is released under this License.
|
||||
|
||||
The "Cover Texts" are certain short passages of text that are listed,
|
||||
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
|
||||
the Document is released under this License.
|
||||
|
||||
A "Transparent" copy of the Document means a machine-readable copy,
|
||||
represented in a format whose specification is available to the
|
||||
general public, whose contents can be viewed and edited directly and
|
||||
straightforwardly with generic text editors or (for images composed of
|
||||
pixels) generic paint programs or (for drawings) some widely available
|
||||
drawing editor, and that is suitable for input to text formatters or
|
||||
for automatic translation to a variety of formats suitable for input
|
||||
to text formatters. A copy made in an otherwise Transparent file
|
||||
format whose markup has been designed to thwart or discourage
|
||||
subsequent modification by readers is not Transparent. A copy that is
|
||||
not "Transparent" is called "Opaque".
|
||||
|
||||
Examples of suitable formats for Transparent copies include plain
|
||||
ASCII without markup, Texinfo input format, LaTeX input format, SGML
|
||||
or XML using a publicly available DTD, and standard-conforming simple
|
||||
HTML designed for human modification. Opaque formats include
|
||||
PostScript, PDF, proprietary formats that can be read and edited only
|
||||
by proprietary word processors, SGML or XML for which the DTD and/or
|
||||
processing tools are not generally available, and the
|
||||
machine-generated HTML produced by some word processors for output
|
||||
purposes only.
|
||||
|
||||
The "Title Page" means, for a printed book, the title page itself,
|
||||
plus such following pages as are needed to hold, legibly, the material
|
||||
this License requires to appear in the title page. For works in
|
||||
formats which do not have any title page as such, "Title Page" means
|
||||
the text near the most prominent appearance of the work's title,
|
||||
preceding the beginning of the body of the text.
|
||||
|
||||
|
||||
2. VERBATIM COPYING
|
||||
|
||||
You may copy and distribute the Document in any medium, either
|
||||
commercially or noncommercially, provided that this License, the
|
||||
copyright notices, and the license notice saying this License applies
|
||||
to the Document are reproduced in all copies, and that you add no other
|
||||
conditions whatsoever to those of this License. You may not use
|
||||
technical measures to obstruct or control the reading or further
|
||||
copying of the copies you make or distribute. However, you may accept
|
||||
compensation in exchange for copies. If you distribute a large enough
|
||||
number of copies you must also follow the conditions in section 3.
|
||||
|
||||
You may also lend copies, under the same conditions stated above, and
|
||||
you may publicly display copies.
|
||||
|
||||
|
||||
3. COPYING IN QUANTITY
|
||||
|
||||
If you publish printed copies of the Document numbering more than 100,
|
||||
and the Document's license notice requires Cover Texts, you must enclose
|
||||
the copies in covers that carry, clearly and legibly, all these Cover
|
||||
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
|
||||
the back cover. Both covers must also clearly and legibly identify
|
||||
you as the publisher of these copies. The front cover must present
|
||||
the full title with all words of the title equally prominent and
|
||||
visible. You may add other material on the covers in addition.
|
||||
Copying with changes limited to the covers, as long as they preserve
|
||||
the title of the Document and satisfy these conditions, can be treated
|
||||
as verbatim copying in other respects.
|
||||
|
||||
If the required texts for either cover are too voluminous to fit
|
||||
legibly, you should put the first ones listed (as many as fit
|
||||
reasonably) on the actual cover, and continue the rest onto adjacent
|
||||
pages.
|
||||
|
||||
If you publish or distribute Opaque copies of the Document numbering
|
||||
more than 100, you must either include a machine-readable Transparent
|
||||
copy along with each Opaque copy, or state in or with each Opaque copy
|
||||
a publicly-accessible computer-network location containing a complete
|
||||
Transparent copy of the Document, free of added material, which the
|
||||
general network-using public has access to download anonymously at no
|
||||
charge using public-standard network protocols. If you use the latter
|
||||
option, you must take reasonably prudent steps, when you begin
|
||||
distribution of Opaque copies in quantity, to ensure that this
|
||||
Transparent copy will remain thus accessible at the stated location
|
||||
until at least one year after the last time you distribute an Opaque
|
||||
copy (directly or through your agents or retailers) of that edition to
|
||||
the public.
|
||||
|
||||
It is requested, but not required, that you contact the authors of the
|
||||
Document well before redistributing any large number of copies, to give
|
||||
them a chance to provide you with an updated version of the Document.
|
||||
|
||||
|
||||
4. MODIFICATIONS
|
||||
|
||||
You may copy and distribute a Modified Version of the Document under
|
||||
the conditions of sections 2 and 3 above, provided that you release
|
||||
the Modified Version under precisely this License, with the Modified
|
||||
Version filling the role of the Document, thus licensing distribution
|
||||
and modification of the Modified Version to whoever possesses a copy
|
||||
of it. In addition, you must do these things in the Modified Version:
|
||||
|
||||
A. Use in the Title Page (and on the covers, if any) a title distinct
|
||||
from that of the Document, and from those of previous versions
|
||||
(which should, if there were any, be listed in the History section
|
||||
of the Document). You may use the same title as a previous version
|
||||
if the original publisher of that version gives permission.
|
||||
B. List on the Title Page, as authors, one or more persons or entities
|
||||
responsible for authorship of the modifications in the Modified
|
||||
Version, together with at least five of the principal authors of the
|
||||
Document (all of its principal authors, if it has less than five).
|
||||
C. State on the Title page the name of the publisher of the
|
||||
Modified Version, as the publisher.
|
||||
D. Preserve all the copyright notices of the Document.
|
||||
E. Add an appropriate copyright notice for your modifications
|
||||
adjacent to the other copyright notices.
|
||||
F. Include, immediately after the copyright notices, a license notice
|
||||
giving the public permission to use the Modified Version under the
|
||||
terms of this License, in the form shown in the Addendum below.
|
||||
G. Preserve in that license notice the full lists of Invariant Sections
|
||||
and required Cover Texts given in the Document's license notice.
|
||||
H. Include an unaltered copy of this License.
|
||||
I. Preserve the section entitled "History", and its title, and add to
|
||||
it an item stating at least the title, year, new authors, and
|
||||
publisher of the Modified Version as given on the Title Page. If
|
||||
there is no section entitled "History" in the Document, create one
|
||||
stating the title, year, authors, and publisher of the Document as
|
||||
given on its Title Page, then add an item describing the Modified
|
||||
Version as stated in the previous sentence.
|
||||
J. Preserve the network location, if any, given in the Document for
|
||||
public access to a Transparent copy of the Document, and likewise
|
||||
the network locations given in the Document for previous versions
|
||||
it was based on. These may be placed in the "History" section.
|
||||
You may omit a network location for a work that was published at
|
||||
least four years before the Document itself, or if the original
|
||||
publisher of the version it refers to gives permission.
|
||||
K. In any section entitled "Acknowledgements" or "Dedications",
|
||||
preserve the section's title, and preserve in the section all the
|
||||
substance and tone of each of the contributor acknowledgements
|
||||
and/or dedications given therein.
|
||||
L. Preserve all the Invariant Sections of the Document,
|
||||
unaltered in their text and in their titles. Section numbers
|
||||
or the equivalent are not considered part of the section titles.
|
||||
M. Delete any section entitled "Endorsements". Such a section
|
||||
may not be included in the Modified Version.
|
||||
N. Do not retitle any existing section as "Endorsements"
|
||||
or to conflict in title with any Invariant Section.
|
||||
|
||||
If the Modified Version includes new front-matter sections or
|
||||
appendices that qualify as Secondary Sections and contain no material
|
||||
copied from the Document, you may at your option designate some or all
|
||||
of these sections as invariant. To do this, add their titles to the
|
||||
list of Invariant Sections in the Modified Version's license notice.
|
||||
These titles must be distinct from any other section titles.
|
||||
|
||||
You may add a section entitled "Endorsements", provided it contains
|
||||
nothing but endorsements of your Modified Version by various
|
||||
parties--for example, statements of peer review or that the text has
|
||||
been approved by an organization as the authoritative definition of a
|
||||
standard.
|
||||
|
||||
You may add a passage of up to five words as a Front-Cover Text, and a
|
||||
passage of up to 25 words as a Back-Cover Text, to the end of the list
|
||||
of Cover Texts in the Modified Version. Only one passage of
|
||||
Front-Cover Text and one of Back-Cover Text may be added by (or
|
||||
through arrangements made by) any one entity. If the Document already
|
||||
includes a cover text for the same cover, previously added by you or
|
||||
by arrangement made by the same entity you are acting on behalf of,
|
||||
you may not add another; but you may replace the old one, on explicit
|
||||
permission from the previous publisher that added the old one.
|
||||
|
||||
The author(s) and publisher(s) of the Document do not by this License
|
||||
give permission to use their names for publicity for or to assert or
|
||||
imply endorsement of any Modified Version.
|
||||
|
||||
|
||||
5. COMBINING DOCUMENTS
|
||||
|
||||
You may combine the Document with other documents released under this
|
||||
License, under the terms defined in section 4 above for modified
|
||||
versions, provided that you include in the combination all of the
|
||||
Invariant Sections of all of the original documents, unmodified, and
|
||||
list them all as Invariant Sections of your combined work in its
|
||||
license notice.
|
||||
|
||||
The combined work need only contain one copy of this License, and
|
||||
multiple identical Invariant Sections may be replaced with a single
|
||||
copy. If there are multiple Invariant Sections with the same name but
|
||||
different contents, make the title of each such section unique by
|
||||
adding at the end of it, in parentheses, the name of the original
|
||||
author or publisher of that section if known, or else a unique number.
|
||||
Make the same adjustment to the section titles in the list of
|
||||
Invariant Sections in the license notice of the combined work.
|
||||
|
||||
In the combination, you must combine any sections entitled "History"
|
||||
in the various original documents, forming one section entitled
|
||||
"History"; likewise combine any sections entitled "Acknowledgements",
|
||||
and any sections entitled "Dedications". You must delete all sections
|
||||
entitled "Endorsements."
|
||||
|
||||
|
||||
6. COLLECTIONS OF DOCUMENTS
|
||||
|
||||
You may make a collection consisting of the Document and other documents
|
||||
released under this License, and replace the individual copies of this
|
||||
License in the various documents with a single copy that is included in
|
||||
the collection, provided that you follow the rules of this License for
|
||||
verbatim copying of each of the documents in all other respects.
|
||||
|
||||
You may extract a single document from such a collection, and distribute
|
||||
it individually under this License, provided you insert a copy of this
|
||||
License into the extracted document, and follow this License in all
|
||||
other respects regarding verbatim copying of that document.
|
||||
|
||||
|
||||
7. AGGREGATION WITH INDEPENDENT WORKS
|
||||
|
||||
A compilation of the Document or its derivatives with other separate
|
||||
and independent documents or works, in or on a volume of a storage or
|
||||
distribution medium, does not as a whole count as a Modified Version
|
||||
of the Document, provided no compilation copyright is claimed for the
|
||||
compilation. Such a compilation is called an "aggregate", and this
|
||||
License does not apply to the other self-contained works thus compiled
|
||||
with the Document, on account of their being thus compiled, if they
|
||||
are not themselves derivative works of the Document.
|
||||
|
||||
If the Cover Text requirement of section 3 is applicable to these
|
||||
copies of the Document, then if the Document is less than one quarter
|
||||
of the entire aggregate, the Document's Cover Texts may be placed on
|
||||
covers that surround only the Document within the aggregate.
|
||||
Otherwise they must appear on covers around the whole aggregate.
|
||||
|
||||
|
||||
8. TRANSLATION
|
||||
|
||||
Translation is considered a kind of modification, so you may
|
||||
distribute translations of the Document under the terms of section 4.
|
||||
Replacing Invariant Sections with translations requires special
|
||||
permission from their copyright holders, but you may include
|
||||
translations of some or all Invariant Sections in addition to the
|
||||
original versions of these Invariant Sections. You may include a
|
||||
translation of this License provided that you also include the
|
||||
original English version of this License. In case of a disagreement
|
||||
between the translation and the original English version of this
|
||||
License, the original English version will prevail.
|
||||
|
||||
|
||||
9. TERMINATION
|
||||
|
||||
You may not copy, modify, sublicense, or distribute the Document except
|
||||
as expressly provided for under this License. Any other attempt to
|
||||
copy, modify, sublicense or distribute the Document is void, and will
|
||||
automatically terminate your rights under this License. However,
|
||||
parties who have received copies, or rights, from you under this
|
||||
License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
|
||||
10. FUTURE REVISIONS OF THIS LICENSE
|
||||
|
||||
The Free Software Foundation may publish new, revised versions
|
||||
of the GNU Free Documentation License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns. See
|
||||
http://www.gnu.org/copyleft/.
|
||||
|
||||
Each version of the License is given a distinguishing version number.
|
||||
If the Document specifies that a particular numbered version of this
|
||||
License "or any later version" applies to it, you have the option of
|
||||
following the terms and conditions either of that specified version or
|
||||
of any later version that has been published (not as a draft) by the
|
||||
Free Software Foundation. If the Document does not specify a version
|
||||
number of this License, you may choose any version ever published (not
|
||||
as a draft) by the Free Software Foundation.
|
||||
|
||||
|
||||
ADDENDUM: How to use this License for your documents
|
||||
|
||||
To use this License in a document you have written, include a copy of
|
||||
the License in the document and put the following copyright and
|
||||
license notices just after the title page:
|
||||
|
||||
Copyright (c) YEAR YOUR NAME.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1
|
||||
or any later version published by the Free Software Foundation;
|
||||
with the Invariant Sections being LIST THEIR TITLES, with the
|
||||
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
|
||||
A copy of the license is included in the section entitled "GNU
|
||||
Free Documentation License".
|
||||
|
||||
If you have no Invariant Sections, write "with no Invariant Sections"
|
||||
instead of saying which ones are invariant. If you have no
|
||||
Front-Cover Texts, write "no Front-Cover Texts" instead of
|
||||
"Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
|
||||
|
||||
If your document contains nontrivial examples of program code, we
|
||||
recommend releasing these examples in parallel under your choice of
|
||||
free software license, such as the GNU General Public License,
|
||||
to permit their use in free software.
|
||||
|
||||
</pre>
|
||||
|
||||
</body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
119
WINGs_tutorial/FifthWindow.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#define MARGIN 14
|
||||
#define WINWIDTH 300
|
||||
#define WINHEIGHT 400
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
|
||||
WMWindow *win;
|
||||
WMSize ButtonsetSize;
|
||||
|
||||
WMText *text;
|
||||
WMColor *color;
|
||||
WMFrame *controlframe;
|
||||
|
||||
char textbuf[40];
|
||||
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
WMDestroyWidget(self);
|
||||
fprintf(stderr,"I've been used!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void selectFiles(void *self, void *data){
|
||||
int i=0;
|
||||
WMOpenPanel *oPanel;
|
||||
oPanel = WMGetOpenPanel(screen);
|
||||
if (WMRunModalFilePanelForDirectory(oPanel, NULL, "/tmp",
|
||||
"Search..", NULL) == True){
|
||||
snprintf(textbuf,39,"%s\n-", WMGetFilePanelFileName(oPanel));
|
||||
WMFreezeText(text);
|
||||
WMAppendTextStream(text,textbuf);
|
||||
WMThawText(text);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
static void handleEvents(XEvent *event, void *data){
|
||||
WMWidget *widget = (WMWidget*)data;
|
||||
switch (event->type) {
|
||||
case ButtonPress:
|
||||
snprintf(textbuf,39,"Button down at (%i,%i) \n-",event->xbutton.x,event->xbutton.y);
|
||||
WMFreezeText(text);
|
||||
WMAppendTextStream(text,textbuf);
|
||||
WMThawText(text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void resizeHandler(void *self, WMNotification *notif){
|
||||
WMSize size = WMGetViewSize(WMWidgetView(win));
|
||||
WMMoveWidget(controlframe, size.width-ButtonsetSize.width, size.height-ButtonsetSize.height);
|
||||
WMResizeWidget(text, size.width-MARGIN -10, size.height-80);
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv){
|
||||
|
||||
WMButton *Button;
|
||||
|
||||
WMInitializeApplication("FifthWindow", &argc, argv);
|
||||
if (!(display = XOpenDisplay(""))){
|
||||
fprintf(stderr,"err: cannot open display");
|
||||
exit(1);
|
||||
}
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
|
||||
/* window */
|
||||
win = WMCreateWindow(screen, "");
|
||||
WMResizeWidget(win, WINWIDTH, WINHEIGHT);
|
||||
WMSetWindowCloseAction(win, closeAll, NULL);
|
||||
WMCreateEventHandler(WMWidgetView(win), ButtonPressMask,handleEvents, win);
|
||||
color = WMCreateRGBColor(screen, 124<<9,206<<8,162<<8, False);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)win, color);
|
||||
WMSetViewNotifySizeChanges(WMWidgetView(win), True);
|
||||
WMAddNotificationObserver(resizeHandler, NULL, WMViewSizeDidChangeNotification, WMWidgetView(win));
|
||||
|
||||
/* Text area */
|
||||
|
||||
text = WMCreateText(win);
|
||||
WMResizeWidget(text, WINWIDTH-MARGIN, WINHEIGHT -80);
|
||||
WMMoveWidget(text, 10, 10);
|
||||
WMSetTextHasVerticalScroller(text, True);
|
||||
WMSetTextEditable(text, False);
|
||||
|
||||
/* frame and two buttons */
|
||||
|
||||
controlframe=WMCreateFrame(win);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)controlframe, color);
|
||||
WMSetFrameRelief(controlframe,WRFlat);
|
||||
|
||||
Button =WMCreateButton(controlframe,WBTMomentaryPush);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)Button, color);
|
||||
WMSetButtonText (Button, "Files");
|
||||
WMSetButtonAction (Button, selectFiles, NULL);
|
||||
ButtonsetSize = WMGetViewSize(WMWidgetView(Button));
|
||||
WMMoveWidget(Button, MARGIN, MARGIN);
|
||||
|
||||
Button =WMCreateButton(controlframe,WBTMomentaryPush);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)Button, color);
|
||||
WMSetButtonText (Button, "Quit");
|
||||
WMSetButtonAction (Button, closeAll, NULL);
|
||||
WMMoveWidget(Button,2*MARGIN+ButtonsetSize.width, MARGIN);
|
||||
ButtonsetSize.width = 3*MARGIN+2*ButtonsetSize.width;
|
||||
ButtonsetSize.height=2*MARGIN+ButtonsetSize.height;
|
||||
WMResizeWidget(controlframe,ButtonsetSize.width,ButtonsetSize.height);
|
||||
|
||||
WMMapSubwidgets(controlframe);
|
||||
resizeHandler(NULL,NULL);
|
||||
/* end of frame and buttons setup */
|
||||
|
||||
|
||||
WMMapSubwidgets(win);
|
||||
WMMapWidget(win);
|
||||
WMRealizeWidget(win);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
17
WINGs_tutorial/FirstWindow.c
Normal file
@@ -0,0 +1,17 @@
|
||||
int main (int argc, char **argv){
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
WMWindow *win;
|
||||
|
||||
WMInitializeApplication("FirstWindow", &argc, argv);
|
||||
|
||||
display = XOpenDisplay("");
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
win = WMCreateWindow(screen, "");
|
||||
|
||||
WMRealizeWidget(win);
|
||||
WMMapWidget(win);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
}
|
||||
122
WINGs_tutorial/FourthWindow.c
Normal file
@@ -0,0 +1,122 @@
|
||||
#define MARGIN 14
|
||||
#define WINWIDTH 300
|
||||
#define WINHEIGHT 400
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
|
||||
WMButton *Button;
|
||||
WMWindow *win;
|
||||
WMSize ButtonsetSize;
|
||||
|
||||
WMBox *box;
|
||||
WMText *text;
|
||||
WMColor *color;
|
||||
|
||||
char textbuf[40];
|
||||
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
WMDestroyWidget(self);
|
||||
fprintf(stderr,"I've been used!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void selectFiles(void *self, void *data){
|
||||
WMOpenPanel *oPanel;
|
||||
oPanel = WMGetOpenPanel(screen);
|
||||
if (WMRunModalFilePanelForDirectory(oPanel, NULL, "/tmp",
|
||||
"Search..", NULL) == True){
|
||||
snprintf(textbuf,39,"%s\n-", WMGetFilePanelFileName(oPanel));
|
||||
WMFreezeText(text);
|
||||
WMAppendTextStream(text,textbuf);
|
||||
WMThawText(text);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
static void handleEvents(XEvent *event, void *data){
|
||||
WMWidget *widget = (WMWidget*)data;
|
||||
switch (event->type) {
|
||||
case ButtonPress:
|
||||
snprintf(textbuf,39,"Button down at (%i,%i) \n-",event->xbutton.x,event->xbutton.y);
|
||||
WMFreezeText(text);
|
||||
WMAppendTextStream(text,textbuf);
|
||||
WMThawText(text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void resizeHandler(void *self, WMNotification *notif){
|
||||
WMSize size = WMGetViewSize(WMWidgetView(win));
|
||||
WMMoveWidget(box, size.width-ButtonsetSize.width, size.height-ButtonsetSize.height);
|
||||
WMResizeWidget(text, size.width-MARGIN -10, size.height-80);
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv){
|
||||
|
||||
WMInitializeApplication("FourthWindow", &argc, argv);
|
||||
if (!(display = XOpenDisplay(""))){
|
||||
fprintf(stderr,"err: cannot open display");
|
||||
exit(-1);
|
||||
}
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
|
||||
/* window */
|
||||
win = WMCreateWindow(screen, "");
|
||||
WMResizeWidget(win, WINWIDTH, WINHEIGHT);
|
||||
WMSetWindowCloseAction(win, closeAll, NULL);
|
||||
|
||||
color = WMCreateRGBColor(screen, 124<<9,206<<8,162<<8, False);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)win, color);
|
||||
|
||||
WMCreateEventHandler(WMWidgetView(win), ButtonPressMask,handleEvents, win);
|
||||
WMSetViewNotifySizeChanges(WMWidgetView(win), True);
|
||||
WMAddNotificationObserver(resizeHandler, NULL, WMViewSizeDidChangeNotification, WMWidgetView(win));
|
||||
|
||||
/* Text area */
|
||||
|
||||
text = WMCreateText(win);
|
||||
WMResizeWidget(text, WINWIDTH-MARGIN, WINHEIGHT -80);
|
||||
WMMoveWidget(text, 10, 10);
|
||||
WMSetTextHasVerticalScroller(text, True);
|
||||
WMSetTextEditable(text, False);
|
||||
WMSetTextIgnoresNewline(text, False);
|
||||
|
||||
/* box with buttons */
|
||||
box=WMCreateBox(win);
|
||||
WMSetBoxBorderWidth(box, MARGIN);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)box, color);
|
||||
WMSetBoxHorizontal(box, True);
|
||||
|
||||
|
||||
Button =WMCreateButton(box,WBTMomentaryPush);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)Button, color);
|
||||
WMSetButtonText (Button, "Files");
|
||||
WMSetButtonAction (Button, selectFiles, NULL);
|
||||
WMMapWidget(Button);
|
||||
ButtonsetSize = WMGetViewSize(WMWidgetView(Button));
|
||||
|
||||
WMAddBoxSubview(box, WMWidgetView(Button), True, False, 60, 1000, MARGIN);
|
||||
|
||||
Button =WMCreateButton(box,WBTMomentaryPush);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)Button, color);
|
||||
WMSetButtonText (Button, "Quit");
|
||||
WMSetButtonAction (Button, closeAll, NULL);
|
||||
WMMapWidget(Button);
|
||||
|
||||
WMAddBoxSubview(box, WMWidgetView(Button), True,False, 60, 1000, 0);
|
||||
WMResizeWidget(box, 4*MARGIN+2*ButtonsetSize.width,2*MARGIN+ButtonsetSize.height);
|
||||
ButtonsetSize =WMGetViewSize(WMWidgetView(box));
|
||||
resizeHandler(NULL,NULL);
|
||||
/* end of box and buttons setup */
|
||||
|
||||
WMMapWidget(win);
|
||||
|
||||
WMMapSubwidgets(win);
|
||||
WMRealizeWidget(win);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
206
WINGs_tutorial/NinthWindow.c
Normal file
@@ -0,0 +1,206 @@
|
||||
#include "editmenu.h" /* This must be the MODIFIED .h file */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#define WINWIDTH 300
|
||||
#define WINHEIGHT 400
|
||||
#define MENUWIDTH 85
|
||||
#define MENITEMHT 21
|
||||
#define LOGPROGRAM "xconsole"
|
||||
#define ERRMSGFIFO "/tmp/WINGsWindowfifo"
|
||||
#define FIFONAMELEN 20
|
||||
#define NOLOGWINDOW (-2) /* value when there is no console window */
|
||||
#define FIFOERROR (-1) /* value when there is a problem w/ console */
|
||||
#define FIFOLOWESTPOSS 0
|
||||
|
||||
|
||||
int windowCounter=0;
|
||||
int fifonr;
|
||||
int sibpid;
|
||||
char fifofilename[FIFONAMELEN+5];
|
||||
|
||||
struct dataStruct{
|
||||
WMWindow *window;
|
||||
WEditMenu *menu;
|
||||
} dataStruct;
|
||||
|
||||
|
||||
/* functions for the message window part: */
|
||||
|
||||
void redirectmsg(int sig){
|
||||
|
||||
// clean up after SIGCHLD, and set fifonr to flag it
|
||||
fifonr=NOLOGWINDOW;
|
||||
if (!access(fifofilename,F_OK|W_OK))
|
||||
unlink(fifofilename);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int showMessageWindow(){
|
||||
|
||||
sprintf(fifofilename,"%s%i",ERRMSGFIFO,(unsigned short)getpid());
|
||||
|
||||
(void) signal(SIGCHLD,redirectmsg); // clean up if message console is killed
|
||||
|
||||
if(access(fifofilename,F_OK)==-1)
|
||||
fifonr=mknod(fifofilename,0640|O_EXCL|S_IFIFO,(dev_t)0);
|
||||
else {fifonr=FIFOERROR;
|
||||
wwarning("Fifo file already exists\n");
|
||||
}
|
||||
/* fifonr == FIFOERROR if mknod/mkfifo or access failed, mknod returns -1 on failure */
|
||||
|
||||
if(fifonr!=FIFOERROR){
|
||||
|
||||
sibpid=fork();
|
||||
if(sibpid==0){
|
||||
execlp(LOGPROGRAM , LOGPROGRAM, "-file",fifofilename,"-geometry","250x400", "-title","Window Messages",(char *)0);
|
||||
exit(1);
|
||||
}else
|
||||
fifonr=open(fifofilename,O_WRONLY);
|
||||
}
|
||||
return fifonr;
|
||||
}
|
||||
|
||||
/* general and menu handling functions */
|
||||
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
|
||||
WMDestroyWidget(self);
|
||||
if(--windowCounter<1){
|
||||
if (fifonr>=FIFOLOWESTPOSS)
|
||||
kill(sibpid,SIGTERM);
|
||||
if (!access(fifofilename,F_OK|W_OK))
|
||||
unlink(fifofilename);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void menuItemAction(void *self, void *data){
|
||||
|
||||
if (fifonr<FIFOLOWESTPOSS)fifonr=showMessageWindow(); // try again in case FIFOERROR
|
||||
if (fifonr==FIFOERROR) // give up and print to stderr
|
||||
fprintf(stderr,"%i: %s selected\n", getpid(), WGetEditMenuItemTitle(self));
|
||||
else{
|
||||
char textbuffer[100];
|
||||
snprintf(textbuffer,100, "%i: %s selected\n", getpid(), WGetEditMenuItemTitle(self));
|
||||
write(fifonr, textbuffer,strlen(textbuffer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void menuItemCloseAction(void *self, void *data){
|
||||
|
||||
WMPostNotificationName("WMWindowClose", self, NULL);
|
||||
}
|
||||
|
||||
|
||||
void getMenu(WMWidget *self, void *data){
|
||||
|
||||
WMPoint position;
|
||||
struct dataStruct *tmp=(struct dataStruct *)data;
|
||||
|
||||
if(WMGetButtonSelected(self)){
|
||||
position=WMGetViewScreenPosition(WMWidgetView(tmp->window));
|
||||
WEditMenuShowAt(tmp->menu,(position.x>MENUWIDTH)?position.x-MENUWIDTH:0, position.y+MENITEMHT,tmp->window);
|
||||
}else{
|
||||
WEditMenuHide(tmp->menu);
|
||||
WDeselectItem(tmp->menu); // remove selection before next pop up
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void notificationHandler(void *self, WMNotification *notif){
|
||||
|
||||
if(!strcmp("WMWindowClose",WMGetNotificationName(notif)))
|
||||
closeAll(self,NULL);
|
||||
if(!strcmp(WMViewSizeDidChangeNotification,WMGetNotificationName(notif))){
|
||||
//resize actions
|
||||
WMSize size = WMGetViewSize(WMWidgetView(self));
|
||||
}
|
||||
}
|
||||
|
||||
/* main widget creating functions */
|
||||
|
||||
WMWindow * makeMainwindow(Display *display, WMScreen *screen){
|
||||
WMWindow *window;
|
||||
|
||||
window = WMCreateWindow(screen, "Menu");
|
||||
WMResizeWidget(window, WINWIDTH, WINHEIGHT);
|
||||
WMSetWindowCloseAction(window, closeAll, NULL);
|
||||
WMAddNotificationObserver(notificationHandler, window, "WMWindowClose", WMWidgetView(window));
|
||||
WMSetViewNotifySizeChanges(WMWidgetView(window), True);
|
||||
WMAddNotificationObserver(notificationHandler, window, WMViewSizeDidChangeNotification, WMWidgetView(window));
|
||||
WMAddNotificationObserver(notificationHandler, window, "WMWindowClose", NULL);
|
||||
WMRealizeWidget(window);
|
||||
return window;
|
||||
}
|
||||
|
||||
|
||||
WEditMenu * makeMenus(WMScreen *screen,WEditMenu *menu, WEditMenu *submenu){
|
||||
WEditMenuItem * menuitem;
|
||||
|
||||
submenu=WCreateEditMenu(screen,"Submenu");
|
||||
menuitem =WAddMenuItemWithTitle(submenu,"Submenu item");
|
||||
WSetEditMenuItemAction( menuitem, menuItemAction);
|
||||
menuitem =WAddMenuItemWithTitle(submenu,"2nd submenu item");
|
||||
WSetEditMenuItemAction( menuitem, menuItemAction);
|
||||
menuitem =WAddMenuItemWithTitle(submenu,"3d submenu item");
|
||||
WSetEditMenuItemAction( menuitem, menuItemAction);
|
||||
menu=WCreateEditMenu(screen,"Main menu");
|
||||
menuitem = WAddMenuItemWithTitle(menu,"1st main item");
|
||||
WSetEditMenuItemAction( menuitem, menuItemAction);
|
||||
menuitem = WAddMenuItemWithTitle(menu,"2nd main item");
|
||||
WSetEditMenuItemAction( menuitem, menuItemAction);
|
||||
menuitem = WAddMenuItemWithTitle(menu,"To submenu");
|
||||
WSetEditMenuSubmenu(menu, menuitem , submenu);
|
||||
menuitem = WAddMenuItemWithTitle(menu,"Quit");
|
||||
WSetEditMenuItemAction( menuitem, menuItemCloseAction);
|
||||
WMRealizeWidget(submenu);WMRealizeWidget(menu);
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
WMButton * makeButtonsTop( WMWidget *window, void *AppData){
|
||||
WMButton *Button;
|
||||
|
||||
Button =WMCreateButton(window,WBTPushOnPushOff);
|
||||
WMSetButtonText (Button, "Menu");
|
||||
WMSetButtonAction (Button, getMenu, AppData);
|
||||
WMMoveWidget(Button, 4,2);
|
||||
WMRealizeWidget(Button);
|
||||
return Button;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv){
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
WMWindow *mainwindow;
|
||||
WEditMenu *submenu, *menu;
|
||||
WEditMenuItem * menuitem;
|
||||
struct dataStruct Mainmenu;
|
||||
WMButton *menubutton;
|
||||
|
||||
fifonr=NOLOGWINDOW;
|
||||
|
||||
WMInitializeApplication("MenuWindow", &argc, argv);
|
||||
display = XOpenDisplay("");
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
mainwindow= makeMainwindow(display, screen) ;
|
||||
|
||||
menu=makeMenus(screen,menu,submenu);
|
||||
|
||||
Mainmenu.window=mainwindow;
|
||||
Mainmenu.menu=menu;
|
||||
menubutton=makeButtonsTop(mainwindow, &Mainmenu);
|
||||
|
||||
WMMapSubwidgets(mainwindow);
|
||||
WMMapWidget(mainwindow);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
return 0;
|
||||
}
|
||||
34
WINGs_tutorial/SecondWindow.c
Normal file
@@ -0,0 +1,34 @@
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
fprintf(stderr,"I've been used!\n");
|
||||
WMDestroyWidget(self);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv){
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
|
||||
WMWindow *win;
|
||||
WMColor *color;
|
||||
|
||||
WMInitializeApplication("SecondWin", &argc, argv);
|
||||
|
||||
if (!(display = XOpenDisplay(""))){
|
||||
fprintf(stderr, "cannot open display\n");
|
||||
exit(1);
|
||||
}
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
|
||||
win = WMCreateWindow(screen, "");
|
||||
WMSetWindowCloseAction(win, closeAll, NULL);
|
||||
color = WMCreateRGBColor(screen,124<<9,206<<8,162<<8, False);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)win, color);
|
||||
|
||||
WMMapWidget(win);
|
||||
WMRealizeWidget(win);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
100
WINGs_tutorial/SeventhWindow.c
Normal file
@@ -0,0 +1,100 @@
|
||||
#include <WINGs/WINGs.h>
|
||||
#include <WINGs/WINGsP.h>
|
||||
|
||||
#define HOFF 40
|
||||
#define VOFF 160
|
||||
#define WINWIDTH 180
|
||||
#define WINHEIGHT 300
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
WMPixmap* pixmap;
|
||||
|
||||
struct _pict{
|
||||
Drawable dwin;
|
||||
XSegment segments[40];
|
||||
int seglen;
|
||||
} pic;
|
||||
|
||||
GC gc, g3;
|
||||
|
||||
void closeAction(WMWidget *self,void *data){
|
||||
WMDestroyWidget(self);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void drawProcedure(XEvent *event, void *data){
|
||||
|
||||
WMDrawPixmap(pixmap, ((struct _pict*)data)->dwin,HOFF,30);
|
||||
XDrawRectangle(display,((struct _pict*)data)->dwin,g3, HOFF,VOFF,100,100);
|
||||
XFillRectangle(screen->display, ((struct _pict*)data)->dwin , WMColorGC(screen->white), HOFF, VOFF, 100, 100);
|
||||
XDrawSegments(display, ((struct _pict*)data)->dwin, WMColorGC(screen->black), ((struct _pict*)data)->segments, ((struct _pict*)data)->seglen);
|
||||
XFlush(display);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv){
|
||||
int i,j;
|
||||
WMColor *color;
|
||||
WMWindow * win;
|
||||
RImage *image;
|
||||
struct _pict pict;
|
||||
Drawable de;
|
||||
|
||||
RColor one, two={0xaf, 0x0f,0xff,0x33};
|
||||
one.red=247;
|
||||
one.green=251;
|
||||
one.blue=107;
|
||||
one.alpha=0xff;
|
||||
|
||||
|
||||
WMInitializeApplication("DrawWin", &argc, argv);
|
||||
display = XOpenDisplay("");
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
win = WMCreateWindow(screen, "");
|
||||
WMResizeWidget(win, WINWIDTH, WINHEIGHT);
|
||||
WMSetWindowCloseAction(win, closeAction, NULL);
|
||||
WMSetWindowTitle(win,"Graphics");
|
||||
color = WMCreateRGBColor(screen,124<<9,206<<8,162<<8, False);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)win, color);
|
||||
/* end setup main window */
|
||||
|
||||
image=RCreateImage( 100,100,0.5);
|
||||
RFillImage(image, &two);
|
||||
RDrawLine(image, 50,10,90,90,&one);
|
||||
RDrawLine(image, 10,90,50,10,&one);
|
||||
RDrawLine(image, 10,90,90,90,&one);
|
||||
|
||||
g3=WMColorGC(screen->gray);
|
||||
XSetLineAttributes(display,g3,3,LineSolid,CapButt,JoinMiter);
|
||||
|
||||
pict.segments[1].x1= pict.segments[0].x1=HOFF;
|
||||
pict.segments[0].x2=HOFF;
|
||||
pict.segments[0].y1=VOFF;
|
||||
pict.segments[1].y2= pict.segments[0].y2=VOFF;
|
||||
pict.segments[1].x2= HOFF+10;
|
||||
pict.segments[1].y1=VOFF+10;
|
||||
pict.seglen=2;
|
||||
for (i=9;i>0;i--){
|
||||
j=2*(10-i);
|
||||
pict.segments[j+1].x1= pict.segments[j].x1=HOFF;
|
||||
pict.segments[j+1].y2= pict.segments[j].y2=VOFF;
|
||||
pict.segments[j].x2= i+pict.segments[j-1].x2;
|
||||
pict.segments[j].y1=i+pict.segments[j-1].y1;
|
||||
pict.segments[j+1].x2= i+pict.segments[j].x2;
|
||||
pict.segments[j+1].y1=i+pict.segments[j].y1;
|
||||
pict.seglen+=2;
|
||||
};
|
||||
|
||||
|
||||
WMRealizeWidget(win);
|
||||
|
||||
pict.dwin=W_VIEW_DRAWABLE(WMWidgetView(win));
|
||||
pixmap=WMCreatePixmapFromRImage(screen, image,1);
|
||||
|
||||
WMCreateEventHandler(WMWidgetView(win), ExposureMask,drawProcedure,&pict);
|
||||
|
||||
WMMapWidget(win);
|
||||
WMScreenMainLoop(screen);
|
||||
}
|
||||
58
WINGs_tutorial/SixthWindow.c
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <WINGs/WINGs.h>
|
||||
#include <WINGs/WINGsP.h>
|
||||
|
||||
#define WINWIDTH 200
|
||||
#define WINHEIGHT 300
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
WMPixmap* pixmap;
|
||||
|
||||
void closeAction(WMWidget *self,void *data){
|
||||
WMDestroyWidget(self);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void drawProcedure(XEvent *event, void *data){
|
||||
WMDrawPixmap(pixmap, W_VIEW_DRAWABLE(WMWidgetView(data)),30,30);XFlush(display);
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv){
|
||||
WMColor *color;
|
||||
WMWindow * win;
|
||||
RImage *image;
|
||||
|
||||
RColor one, two={0xaf, 0x0f,0xff,0x33};
|
||||
one.red=0x20;
|
||||
one.green=0x20;
|
||||
one.blue=0x20;
|
||||
one.alpha=0xff;
|
||||
|
||||
|
||||
WMInitializeApplication("DrawWin", &argc, argv);
|
||||
display = XOpenDisplay("");
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
win = WMCreateWindow(screen, "");
|
||||
WMResizeWidget(win, WINWIDTH, WINHEIGHT);
|
||||
WMSetWindowCloseAction(win, closeAction, NULL);
|
||||
WMSetWindowTitle(win,"Graphics");
|
||||
color = WMCreateRGBColor(screen,124<<9,206<<8,162<<8, False);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)win, color);
|
||||
/* end setup main window */
|
||||
|
||||
|
||||
image=RCreateImage( 100,100,.8);
|
||||
RFillImage(image, &two);
|
||||
RDrawLine(image, 50,10,90,90,&one);
|
||||
RDrawLine(image, 10,90,50,10,&one);
|
||||
RDrawLine(image, 10,90,90,90,&one);
|
||||
|
||||
WMRealizeWidget(win);
|
||||
|
||||
pixmap=WMCreatePixmapFromRImage(screen, image,1);
|
||||
WMCreateEventHandler(WMWidgetView(win), ExposureMask,drawProcedure,win);
|
||||
|
||||
WMMapWidget(win);
|
||||
WMScreenMainLoop(screen);
|
||||
}
|
||||
46
WINGs_tutorial/ThirdWindow.c
Normal file
@@ -0,0 +1,46 @@
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
fprintf(stderr, "I've been used!\n");
|
||||
WMDestroyWidget(self);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
handleEvents(XEvent *event, void *data)
|
||||
{
|
||||
WMWidget *widget = (WMWidget*)data;
|
||||
switch (event->type) {
|
||||
case ButtonPress:
|
||||
closeAll(widget,NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char **argv){
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
|
||||
WMWindow *win;
|
||||
WMColor *color;
|
||||
|
||||
WMInitializeApplication("ThirdWindow", &argc, argv);
|
||||
|
||||
if (!(display = XOpenDisplay(""))){
|
||||
fprintf(stderr,"error: cannot open display\n");
|
||||
exit(1);
|
||||
}
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
|
||||
win = WMCreateWindow(screen, "");
|
||||
WMSetWindowCloseAction(win, closeAll, NULL);
|
||||
WMCreateEventHandler(WMWidgetView(win), ButtonPressMask,handleEvents, win);
|
||||
color = WMCreateRGBColor(screen, 124<<9,206<<8,162<<8, False);
|
||||
WMSetWidgetBackgroundColor((WMWidget *)win, color);
|
||||
|
||||
WMMapWidget(win);
|
||||
WMRealizeWidget(win);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
119
WINGs_tutorial/WINGGraphics.html
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0077)WINGGraphics.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="keywords" content="WINGs, tutorial,X11, Xlib,graphics, GUI, Window Maker, OpenGL, Mesa">
|
||||
<meta name="description" content="WINGs library tutorial">
|
||||
<meta name="license" content="GNU Free Documentation License">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGsRemark.html">LAST: Programming Details 1</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGMenu.html">NEXT: Programming Details 3</a></td></tr></tbody></table>
|
||||
|
||||
<h4>Drawing procedures</h4>
|
||||
|
||||
<h5>The drawable</h5>
|
||||
<p>The WINGs library has functions to directly draw an image in a label, button or slider. To write to other widgets, there is a function <code>WMDrawPixmap (WMPixmap *pixmap, Drawable d, int x, int y)</code>. The pixmap can be written to any XLib variable of type <code>Drawable</code>, at position (x,y). This section shows how it is done to a window. The drawable is retrieved from the widget's view structure by the macro <code>W_VIEW_DRAWABLE(WMView)</code>. You <em>only</em> call this macro <em>after</em> the widget has been <code>WMRealizeWidget</code>ed, or there simply will not be a drawable in it. To use it,<code>#include <WINGs/WINGsP.h></code>.
|
||||
</p><p>Images can be created from within the code itself. The WINGs/wraster library creates a structure for it, by the call <code>RCreateImage</code>, and there <a href="WINGLib.html#DrawFunctions">are</a> a few functions to draw a line or segments in it. You would only use this if you like to store the image in memory for some reason. These functions use a colour structure <code>RColor</code>. There is a conversion function from a <code>WMColor</code>, but the RColor is a simple structure with four unsigned long members which are the RGB and alpha values. This <a href="SixthWindow.c">example</a> shows how a picture is drawn directly into a window, by the defined function <code>drawProcedure</code>. This function is called by associating <code>Expose</code> events to it, by using <code>WMCreateEventHandler</code> on the window's view:
|
||||
</p><pre><code>
|
||||
void drawProcedure(XEvent *event, void *data){
|
||||
WMDrawPixmap(pixmap, W_VIEW_DRAWABLE(WMWidgetView(data)),30,30);XFlush(display);
|
||||
}
|
||||
int main (){
|
||||
/* code */
|
||||
WMCreateEventHandler(WMWidgetView(win), ExposureMask,drawProcedure,win);
|
||||
/* */ }</code></pre>
|
||||
<p>
|
||||
Try to comment out the line with the event handler function, and to call <code>WMDrawPixmap(pixmap, W_VIEW_DRAWABLE<wbr>(WMWidgetView(win)),30,30)</code> directly from main. It won't work. When the <code>WMScreenMainLoop</code> starts up, there will be an Expose event. The window will react to the event by drawing itself, as specified in the WINGslib routines, but there won't be another call to WMDrawPixmap, unless you programme it yourself.
|
||||
|
||||
</p><h5>Xlib graphics functions</h5>
|
||||
<p><img src="./WINGGraphics_files/seventh2.jpeg" align="right" width="150">The Xlib library itself offers more possibilities to draw in a widget, like drawing curves. The Xlib functions write to the drawable, like WMDrawPixmap. Xlib functions need the Xlib <code>GC</code> type <a href="WINGsRemark.html#talkGraphicsContext">graphics contexts</a>. You keep different graphics contexts at a time to switch drawing styles. The WMColorGC macro creates one from a WMColor structure, which will give you the color you used as an argument. In the example, the line width in this graphics context is set to 3 instead of one with the function <code>XSetLineAttributes</code>. You'll get this line width whenever you use <code>XMColorGC(screen->gray)</code> from that point on. The next lines are drawn with default line width. The example is <a href="SeventhWindow.c">here</a>.
|
||||
|
||||
</p><p>Useful Xlib functions and structures are
|
||||
</p><ul>
|
||||
<li><code> int XDrawRectangle(Display *display, Drawable d, GC gc,
|
||||
int x, int y, unsigned int width, unsigned int
|
||||
height)</code></li><li><code>
|
||||
int XDrawLines(Display *display, Drawable d, GC gc, XPoint
|
||||
*points, int npoints, int mode)</code></li><li><code>
|
||||
|
||||
int XDrawSegments(Display *display, Drawable d, GC gc,
|
||||
XSegment *segments, int nsegments)</code></li><li><code>
|
||||
|
||||
int XDrawArc(Display *display, Drawable d, GC gc, int x,
|
||||
int y, unsigned int width, unsigned int height, int
|
||||
angle1, int angle2)</code></li><li><code>
|
||||
int XDrawArcs(Display *display, Drawable d, GC gc, XArc
|
||||
*arcs, int narcs)</code></li><li><code>
|
||||
int XDrawPoint(Display *display, Drawable d, GC gc, int x,
|
||||
int y)</code></li><li><code>
|
||||
|
||||
int XDrawPoints(Display *display, Drawable d, GC gc,
|
||||
XPoint *points, int npoints, int mode)</code></li><li><code>
|
||||
|
||||
GC XCreateGC(Display *display, Drawable d, unsigned long
|
||||
valuemask, XGCValues *values)</code></li><li><code>
|
||||
int XFillArc(Display *display, Drawable d, GC gc, int x,
|
||||
int y, unsigned int width, unsigned int height, int
|
||||
angle1, int angle2)</code></li><li><code>
|
||||
int XFillPolygon(Display *display, Drawable d, GC gc,
|
||||
XPoint *points, int npoints, int shape, int mode)</code></li><li><code>
|
||||
|
||||
|
||||
typedef struct {
|
||||
short x1, y1, x2, y2;
|
||||
} XSegment</code></li><li><code>
|
||||
|
||||
typedef struct {
|
||||
short x, y;
|
||||
} XPoint</code></li><li><code>
|
||||
|
||||
|
||||
typedef struct {
|
||||
short x, y;
|
||||
unsigned short width, height;
|
||||
short angle1, angle2; /* Degrees * 64 */
|
||||
} XArc</code>
|
||||
</li></ul>
|
||||
<p>The XFree XLib man pages are <a href="http://www.xfree86.org/current/manindex3.html">here</a> in 2010.
|
||||
|
||||
|
||||
</p><h5><a name="talkOpenGL">An OpenGL drawing area</a></h5>
|
||||
<p><img src="./WINGGraphics_files/glframe.jpeg" align="right" width="20%">Just like the Xlib functions, we can use a drawable for drawing 3 dimensional images with the <a href="http://www.opengl.org/">OpenGL</a>/<a href="http://www.mesa3d.org/">Mesa GL</a> libraries. This section will show how to use a WINGs frame for this. The application shall have a GL-window and one button which allows the user to turn the object in the frame.
|
||||
</p><p>We realize a widget "glframe" of type WMFrame as usual, and get the drawable (win of type Window) out of its view with
|
||||
</p><pre><code>win =W_VIEW_DRAWABLE(WMWidgetView(glframe));</code></pre>
|
||||
To set up the variables needed to use the MesaGL library, we use the glX library. We shall also change some properties of the X-window <code>win</code>. We can retrieve the necessary information for both by way of an RContext, but what we need is so simple, that we shall use Xlib functions to get it directly.
|
||||
<pre><code>Window win;
|
||||
XVisualInfo *xvVisualInfo;
|
||||
Colormap usColorMap;
|
||||
XSetWindowAttributes winAttr;
|
||||
GLXContext glXContext;
|
||||
int Attributes[] = { GLX_RGBA,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 16,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None};
|
||||
xvVisualInfo = glXChooseVisual(display, DefaultScreen(display), Attributes);
|
||||
cmColorMap = XCreateColormap(display,RootWindow(display, DefaultScreen(display)), usVisualInfo->visual, AllocNone);
|
||||
winAttr.colormap = usColorMap;
|
||||
winAttr.border_pixel = 0;
|
||||
winAttr.background_pixel = 0;
|
||||
winAttr.event_mask = ExposureMask | ButtonPressMask |StructureNotifyMask| KeyPressMask;
|
||||
|
||||
XChangeWindowAttributes(display,win,CWBorderPixel | CWColormap | CWEventMask,&winAttr);
|
||||
glXContext = glXCreateContext(display, xvVisualInfo, None, True);
|
||||
glXMakeCurrent(display, win, glXContext);</code></pre>
|
||||
<p>The first thing to get, is an X XVisualInfo structure for the colour properties we need (8 bits for a colour) and depth size. The glX library has the <br><code>glXChooseVisual(Display *display, int screen, int * attributes) </code><br> function for that. We use these data to create a colormap,with the Xlib function <br><code>XCreateColormap(Display *display, Window win, Visual *visual, int alloc)</code>.<br> We then make an Xlib structure <code>XSetWindowAttributes</code>, to which we add the colormap as a member .colormap, and to which we set a member .event_mask by <code>OR</code>ing the necessary masks. This structure, finally, can be used to set the window's properties with <br><code>int XChangeWindowAttributes(Display *display, Window win, unsigned long valuemask, XSetWindowAttributes *attributes)</code>.<br> Having done this, we collect the "environment variables" for OpenGL with the glX function <br><code>GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct )</code>.<br> Finally we select the glframe's drawable <code>win</code> as the window OpenGl shall write to, by <br> <code>Bool glXMakeCurrent( Display *display, GLXDrawable win, GLXContext ctx )</code>.<br> The frame's window <code>Window win</code> can now be used in the GL-call <code>void glXSwapBuffers( Display *display, GLXDrawable win )</code>.
|
||||
</p><p> The source code is in the file <a href="glframe.c">glframe.c</a>. You need to have MesaGL installed, and the glx library. To compile, use <kbd>gcc -x c glframe.c -lXft -L/usr/X11/lib -L/usr/lib -lWINGs -lwraster -lOSMesa -lm -o glframe</kbd>. If the compiler does not find the glx library, you could add <kbd> -L/usr/X11/lib/modules/extensions -lglx</kbd>, if that is where your library is.
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
</p><p>
|
||||
</p><table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGsRemark.html">LAST: Programming Details 1</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGMenu.html">NEXT: Programming Details 3</a></td></tr></tbody></table>
|
||||
|
||||
|
||||
</body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
BIN
WINGs_tutorial/WINGGraphics_files/glframe.jpeg
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
WINGs_tutorial/WINGGraphics_files/seventh2.jpeg
Normal file
|
After Width: | Height: | Size: 11 KiB |
1188
WINGs_tutorial/WINGLib.html
Normal file
BIN
WINGs_tutorial/WINGLib_files/2tabs.jpeg
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
WINGs_tutorial/WINGLib_files/AlertPanel.jpeg
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
WINGs_tutorial/WINGLib_files/Buttons.jpeg
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
WINGs_tutorial/WINGLib_files/ColorPanel.jpeg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
WINGs_tutorial/WINGLib_files/FontPanel.jpeg
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
WINGs_tutorial/WINGLib_files/InputDialog.jpeg
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
WINGs_tutorial/WINGLib_files/Labels.jpeg
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
WINGs_tutorial/WINGLib_files/List.jpeg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
WINGs_tutorial/WINGLib_files/OpenFileDialog.jpeg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
WINGs_tutorial/WINGLib_files/Progress.jpeg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
WINGs_tutorial/WINGLib_files/PullDown.jpeg
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
WINGs_tutorial/WINGLib_files/Slider.jpeg
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
WINGs_tutorial/WINGLib_files/TabView.jpeg
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
BIN
WINGs_tutorial/WINGLib_files/TextField.jpeg
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
WINGs_tutorial/WINGLib_files/scrollview.jpeg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
WINGs_tutorial/WINGLib_files/textarea.jpeg
Normal file
|
After Width: | Height: | Size: 72 KiB |
82
WINGs_tutorial/WINGMenu.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0073)WINGMenu.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="keywords" content="WINGs, tutorial,X11, Xlib,graphics, GUI, hack, Linux">
|
||||
<meta name="description" content="WINGs library tutorial">
|
||||
<meta name="license" content="GNU Free Documentation License">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGGraphics.html">LAST: Programming Details 2</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGLib.html">NEXT: Library description</a></td></tr></tbody></table>
|
||||
|
||||
<h4>Change a widget: a cascading menu</h4>
|
||||
<p>The WINGs library offers functions to set up a structure for a menu with submenus. However, the mapping of the menu itself is left to the Window Maker window manager. Without Window Maker, a menu which has been programmed this way, will not show. The easy way around this, is to use the source code for the editable menu in the WPrefs application, change it to give it the usual menu functionality, and compile this modified source code with the application's code. The two files you need to do this, are in the Window Maker's 0.92 source code directory WPrefs.app. Copy WPrefs.app/editmenu.c and WPrefs.app/editmenu.h to your current directory. A couple of little changes to editmenu.c will be sufficient to give adequate menu/submenu functionality.
|
||||
</p><p>Change the editable menu widget <code>struct W_EditMenuItem</code>. The EditMenuItem structure is the structure which is used to programme the editable menu in the Window Maker Preferences utility. To use it as a regular menu, it needs a pointer to the function which you want to execute when you click the item. Any WINGs widget structure needs to keep <code>W_Class widgetClass</code> and <code>WMView *view</code> as its first two declarations. Insert the line <code>WMAction * callback;</code> somewhere after them. The widget declaration will now be:
|
||||
</p><pre><code>
|
||||
typedef struct W_EditMenuItem {
|
||||
W_Class widgetClass;
|
||||
WMView *view;
|
||||
|
||||
struct W_EditMenu *parent;
|
||||
char *label;
|
||||
WMPixmap *pixmap;
|
||||
void *data;
|
||||
WMCallback *destroyData;
|
||||
WMAction * callback;
|
||||
struct W_EditMenu *submenu;
|
||||
struct {
|
||||
unsigned isTitle:1;
|
||||
unsigned isHighlighted:1;
|
||||
} flags;
|
||||
} EditMenuItem;</code></pre>
|
||||
For convenience, add this function to editmenu.c, too:
|
||||
<pre><code>void WSetEditMenuItemAction(WEditMenuItem *item, WMAction *callback)
|
||||
{
|
||||
item->callback= callback;
|
||||
}</code></pre>
|
||||
|
||||
<p><a name="overrideMenu"><img src="./WINGMenu_files/menu.jpeg" align="right"></a>We shall make a window with one button which will make the menu pop up. The code to create the menu is as follows. Have editmenu.c and editmenu.h in the same directory as the window application code, insert <code>#include "editmenu.h"</code> somewhere at the top.
|
||||
</p><pre><code>
|
||||
WEditMenu *submenu, *menu;
|
||||
WEditMenuItem * menuitem;
|
||||
|
||||
submenu=WCreateEditMenu(screen,"Submenu");
|
||||
menuitem =WAddMenuItemWithTitle(submenu,"Submenu item");
|
||||
menu=WCreateEditMenu(screen,"Main menu");
|
||||
menuitem = WAddMenuItemWithTitle(menu,"To submenu");
|
||||
WSetEditMenuSubmenu(menu, menuitem , submenu);
|
||||
menuitem = WAddMenuItemWithTitle(menu,"Main item");
|
||||
WMRealizeWidget(submenu);
|
||||
WMRealizeWidget(menu);</code></pre>
|
||||
The function to map the window w's menu at point (x,y) is <code>WEditMenuShowAt(menu,x,y,w)</code>. However, it will not show anything unless it is used after the intial window has been mapped. To do this, we use <code>WMSetButtonAction</code> on a button, and make the WMAction map the menu. We pass it pointers to both the menu and the window, so that we can map the menu in the window's neighbourhood. The WMAction will look like :
|
||||
<pre><code>void getMenu(WMWidget *self, void *data){
|
||||
WMPoint position;
|
||||
struct datacouple *tmp=(struct datacouple *)data;
|
||||
if(WMGetButtonSelected(self)){
|
||||
position=WMGetViewScreenPosition(WMWidgetView(tmp->window));
|
||||
WEditMenuShowAt(tmp->menu,(position.x>MENUWIDTH)?position.x-MENUWIDTH:0,\
|
||||
position.y+MENITEMHT,tmp->window);
|
||||
}else
|
||||
WEditMenuHide(tmp->menu);
|
||||
}</code></pre> The used structure is <code>struct datacouple{WMWindow *window; WEditMenu *menu;} datacouple;
|
||||
</code>. Realize the window before the others. The code with details is <a href="EighthWindow.c">here</a>. To compile it, you now type <kbd>cc -x c EighthWindow.c editmenu.c -lXft -L/usr/X11/lib -L/usr/lib -lWINGs -lwraster -o EighthWindow</kbd>. editmenu.c is, of course, the modified source file.
|
||||
<p>To use the callback functions, we need to execute them somewhere. To do this, search the <code>static void selectItem</code> function in the editmenu.c source. After its last line, <a name="talkInsertCallback">insert</a> the line: <code>if (menu->selectedItem->callback) menu->selectedItem->callback(menu->selectedItem,NULL);</code>. Define the callback before main as, eg.:
|
||||
</p><pre><code>void menuItemAction(void *self, void *data){
|
||||
fprintf(stderr, "Selected\n");}</code></pre>
|
||||
and add it to the menu items in the <code>main</code> code with the <code> WSetEditMenuItemAction( menuitem, menuItemAction);</code>. There is also a little addition to the getMenu function, to reset the menu when we hide it.
|
||||
|
||||
<p>The function <code>WCreateEditMenuItem</code> in editmenu.c associates to ButtonPress events on the menu item widget, the function <code>handleItemClick</code>. This event handler function calls the function <code>selectItem</code> when it gets this event, and does a few other things we shall not need any more. The selectItem function goes through a few things. If the clicked menu item is a submenu entry, it checks its location and maps the submenu. At the end of this function we have <a href="WINGMenu.html#talkInsertCallback">inserted</a> the line which calls our callback function in case the pointer to it is not <code>NULL</code>. If the menu has to appear, legacy-style, below a fixed bar in the window's top, we would just need to calculate this position, and also need to hide the menu whenever we drag the window itself. For a free floating menu, the latter is not very important.
|
||||
</p><p>The application source code is <a href="NinthWindow.c">here</a>. The editmenu.c code with the first few changes in it, is <a href="editmenu.c">here</a>. The changes are marked by a comment starting with <code>/* MOD </code>. There is one change in the new <a href="editmenu.h">editmenu.h</a> file.
|
||||
</p><h5>Window manager hints</h5>
|
||||
<p></p><table align="left" width="20%" clear="right"><tbody><tr><td><img src="./WINGMenu_files/redirectmenu1.jpeg" align="left" width="100%"></td></tr><tr><td><img src="./WINGMenu_files/redirectmenu2.jpeg" align="left" width="100%"></td></tr></tbody></table>As the menu does not have the functions of an ordinary application window, we would not want it to have the same window frame. The buttons in the titlebar may be omitted, or limited. This can be done by the window manager, on data obtained from the X server.The X server, in its turn, gets them from the application. The XLib function <code> XSetTransientForHint</code> will, in xfce4, make the menu widget look like the one in the image shown on the left. The window manager gives it a title bar and button. It also allows to drag the menu. The code must provide functions to handle the event that the close button on the title bar is clicked, or the menu window will have the same problem as our <a href="WINGStep1.html#talkMissing">first window</a>. The window manager can also be bypassed. To do this, there is the Xlib function <code> int XChangeWindowAttributes<wbr>(Display *display, Window w,
|
||||
unsigned long valuemask, XSetWindowAttributes
|
||||
*attributes)</code>. As shown in the example code, it can be used to set the window attribute <code>override_redirect</code>. This will block window manager interference with the placement of windows. The menu window will now in all window managers look like the one in the <a href="WINGMenu.html#overrideMenu">first image</a> at the top of this page.
|
||||
<p align="left"><br><br>
|
||||
<br>
|
||||
</p><p>
|
||||
</p><table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGGraphics.html">LAST: Programming Details 2</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGLib.html">NEXT: Library description</a></td></tr></tbody></table>
|
||||
|
||||
|
||||
</body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
BIN
WINGs_tutorial/WINGMenu_files/menu.jpeg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
WINGs_tutorial/WINGMenu_files/redirectmenu1.jpeg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
WINGs_tutorial/WINGMenu_files/redirectmenu2.jpeg
Normal file
|
After Width: | Height: | Size: 14 KiB |
42
WINGs_tutorial/WINGsIntro.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0074)WINGsIntro.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="keywords" content="WINGs, tutorial, Introduction, C, programming, GUI, Window Maker, Linux">
|
||||
<meta name="description" content="WINGs library tutorial">
|
||||
<meta name="license" content="GNU Free Documentation License">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSITFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGtoc.html">LAST: Contents</a></td><td align="RIGHT"><a href="WINGStep1.html">NEXT: Step 1 Drawing a Window</a></td></tr></tbody></table>
|
||||
|
||||
<h3>Make a WINGs based Graphical User Interface in 3 Steps</h3>
|
||||
|
||||
The WINGs library is the library with routines for a graphical user interface which comes with the Window Maker window manager. In 2010 the library's web page is <a href="http://windowmaker.org/development.php?show=wings">here</a> on the windowmaker.org website. You can download windowmaker with the WINGs libraries <a href="http://windowmaker.org/index.php">here</a>. The library provides widgets which you can use to make a graphical user interface. A widget is a software module which is used to interact with the user. Buttons and menus are widgets. The WINGs library offers the possibility to programme these widgets in a few lines of C code, so that you can dedicate the rest of your time to the functionality in your application.
|
||||
|
||||
<p>This tutorial shows in three simple steps how to write a graphical user interface with WINGs. Those three steps will cover all that is needed to write the major dialogs and widgets needed for communication between application and user. It assumes that you know how to programme in C, but you do not need to know anything about GUI-programming.
|
||||
|
||||
</p><p> Step 1 in this tutorial will show the framework for an application which uses a WINGS graphical user interface. It shows how you have the WINGs library create a widget for you, and how you set its properties. Step 2 briefly explains what events are, and how you make your application react to incoming events. This is what makes your interface work. Step 3 shows how to insert two buttons and a text area into the application's window, and how to implement the handling of events for them. Along the explanations in the main text, there are a few examples of source code. Most WINGs function names speak for themselves, and therefore, not everything in the source code is repeated in the text. You can just read the code. The example developed in the three steps is a sufficient blueprint to allow you to use the other widgets in the WINGs library. To do that, just look up the functions in the relevant section in the library description section.
|
||||
|
||||
</p><p>There are three programming detail sections after the three tutorial sections. They explain how to use Xlib code along with the WINGs code, how to set up a widget in which you can draw OpenGL images, and how to change part of the WINGs library source for your own needs, among other things.
|
||||
|
||||
</p><p>To compile WINGs widgets, you need a C-compiler, the WINGs library, and an X-server on your computer. The first few libraries which you need will be libWINGs and libwraster, and the X11 library libXft. If the WINGs library <em>directory</em> is in the /usr/lib path, and your X11 libraries in /usr/X11/lib, you can compile the code with gcc as follows
|
||||
</p><p><kbd>gcc -x c FileName -lXft -L/usr/X11/lib -L/usr/lib -lwraster -lWINGs -o FileName</kbd>
|
||||
</p><p>This will get you a binary called FileName which you can run, either by double clicking, or by running the <kbd>./FileName</kbd> command in an xterm.
|
||||
</p><p> To compile in C++, just replace the <code> fprintf(stderr, ..)</code> command with an appropriate <code>cerr << </code>, add the namespace command, and replace the <stdio.h> with the iostream header, then compile as
|
||||
<kbd>
|
||||
g++ -x c++ -lXft FileName -L/usr/X11/lib -L/usr/lib -lwraster -lWINGs-o FileName</kbd>
|
||||
|
||||
|
||||
|
||||
</p><p>The function prototypes in the library description were retrieved from the information in the WINGs man pages which were compiled by Alexey Voinov. His page was <a href="http://voins.program.ru/windowmaker/wingsman.html">here</a> in 2010.
|
||||
|
||||
|
||||
<br>
|
||||
<br>
|
||||
</p><p>
|
||||
</p><table align="JUSITFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGtoc.html">LAST: Contents</a></td><td align="RIGHT"><a href="WINGStep1.html">NEXT: Step 1 Drawing a Window</a></td></tr></tbody></table>
|
||||
|
||||
|
||||
|
||||
</body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
174
WINGs_tutorial/WINGsRemark.html
Normal file
@@ -0,0 +1,174 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0075)WINGsRemark.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="keywords" content="WINGs, tutorial, Introduction, C, programming, GUI, Window Maker, Linux">
|
||||
<meta name="description" content="WINGs library tutorial">
|
||||
<meta name="license" content="GNU Free Documentation License">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGStep3.html">LAST: Step 3 Adding Widgets</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGGraphics.html">NEXT: Programming Details 2</a></td></tr></tbody></table>
|
||||
|
||||
<h4>Programming details and WINGs functions</h4>
|
||||
|
||||
<h5>Count the windows</h5>
|
||||
In the code up till now, we had just one window. When it receives notificaton that the window is requested to close, it shuts down the whole application. In an application with more windows open, we might not like it when closing an arbitrary window shuts everything down. An obvious solution is to exit the programma when the last open window is requested to close, and keep a count of the number of windows open. The closeAll function becomes:
|
||||
<pre><code>int windowcounter=0;
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
WMDestroyWidget(self);
|
||||
fprintf(stderr,"I've been used!");
|
||||
if(--windowcounter<1) exit(0);
|
||||
}</code></pre>
|
||||
A second window should be opened with the existing screen as an argument. After success in opening, you increase <code>windowcounter</code> by one.
|
||||
<h5><a name="talkIcons">Icons and images</a></h5>
|
||||
<p>Defining an icon which will be used for your application, and drawing an image in a widget, are quite straightforward. Suppose, there is an XPM-image available, and it is the file /usr/include/<wbr>pixmaps/<wbr>picture.xpm. The following code sets an application icon and draws an icon in a label.
|
||||
</p><pre><code>RContext *ctxt;
|
||||
RImage *img;
|
||||
WMPixmap *wimg;
|
||||
/* code to open screen, window*/
|
||||
ctxt=WMScreenRContext(screen);
|
||||
img=RLoadXPM(ctxt, "/usr/include/pixmaps/picture.xpm", 0);
|
||||
WMSetApplicationIconImage(screen, img);
|
||||
wimg= WMCreatePixmapFromRImage(screen, img,0);
|
||||
/* code to create a label */
|
||||
WMSetLabelImagePosition(label, WIPImageOnly);
|
||||
WMSetLabelImage(label, wimg);</code></pre>
|
||||
<code>RContext</code> refers to the X-server's so-called <a name="talkGraphicsContext">graphics context</a>. This specifies which line width, fill patterns, etc. will be used. That information is not contained in the XPM-file. With <code>WMScreenRContext</code>, we use the existing context. <code>RLoadXPM</code> loads the xpm from a file, and stores it as an RImage.
|
||||
<p> The image is set as an icon for the application with this RImage. We transform the RImage into a WMPixmap. The WMPixmap can be shown in a widget. Here, we show it in a label with <code>WMSetLabelImage </code>. You must specify its position with the right <a href="WINGLib.html#ImagePositions">option</a> first.
|
||||
</p><p>An X pixmap is a text file. You can insert its code into your application source code directly, and handle it with <code>RGetImageFromXPMData</code>
|
||||
|
||||
</p><h5><a name="talkResolution">Virtual screen and resolution</a></h5>
|
||||
|
||||
<p>
|
||||
WINGs provide the function <code> unsigned int WMScreenWidth (WMScreen *wmscr)</code> to get the screen's width in pixels. There is a similar function to get its height. This is information about the virtual screen, and is not always what you are looking for. Many (or all?) Gtk+ interfaces have bigger font sizes when the virtual screen is bigger, even when the monitor is the same. If your monitor runs at 1024x768, and your virtual screen measures 1800x1440 pixels, you would often want to adjust your application to the monitor's resolution, and the view it has on the virtual screen, rather than to the screen's size itself. To get the used video mode (ie. the 1024x768 in our example), and the position on the virtual screen, the X-library libXxf86vmode provides two functions.
|
||||
</p><ul>
|
||||
<li><code> Bool XF86VidModeGetModeLine( Display *display, int screen, int *dotclock_return, XF86VidModeModeLine *modeline)</code>
|
||||
</li><li><code> Bool XF86VidModeGetViewPort( Display *display, int screen, int *x_return, int *y_return)</code>
|
||||
</li></ul>
|
||||
The returned <code>modeline</code> is a structure which has members <code>hdisplay</code> and <code>vdisplay</code>. The monitor's current resolution is <code>hdisplay x vdisplay</code>. The monitor's left uppper corner is at the position returned by <code>XF86VidModeGetViewPort</code> in <code>*x_return x *y-return</code>. The <code>screen</code> parameter in these function calls is <em>not</em> a WMScreen variable. A WMScreen variable <code>wmscr</code>is a structure, defined in WINGsP.h, which contains the screen number in a member <code>wmscr.screen</code>. The follwing example defines a function <code>*WMGetModeViewSSize()</code> For simplicity, it is assumed the application is using the default screen. The argument to the <code>WMScreenWidth</code> function should of course be a WMScreen type.
|
||||
|
||||
<pre><code> /* extra headers */
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
|
||||
int *WMGetModeViewSSize(){
|
||||
int *result;
|
||||
XF86VidModeModeLine modeline;
|
||||
int dotclock_return;
|
||||
|
||||
result=(int *)calloc(8,sizeof(int));
|
||||
|
||||
XF86VidModeGetModeLine(display,DefaultScreen(display), &dotclock_return,&modeline);
|
||||
*result= modeline.hdisplay;
|
||||
result[1]= modeline.vdisplay;
|
||||
XF86VidModeGetViewPort(display,DefaultScreen(display), result+2,result+3);
|
||||
result[4]=WMScreenWidth(screen);
|
||||
result[5]=WMScreenHeight(screen);
|
||||
|
||||
return result;
|
||||
}</code></pre>
|
||||
<img src="./WINGsRemark_files/ScreenSize.jpeg" align="right" width="50%">To compile this function, you need the <kbd>libXxf86vm</kbd> library. For the GNU compiler, your command would now be <kbd>gcc -x c -lXft FileName.c -L/usr/X11/lib -L/usr/lib -lWINGs -lwraster -lXxf86vm -o FileName</kbd>. When you run the function (after opening the screen), and print its results, you will find something like: <pre><code>result 0 and 1: 1024 768
|
||||
result 2 and 3: 126 171
|
||||
result 4 and 5: 1800 1440</code></pre>
|
||||
meaning that the monitor is running at 1024x768, its upper left corner is at (126,171) in the virtual screen, and the whole screen has a resolution of 1800x1440. The user is seeing the screen part from (126,171) to (1150,939). In the illustration to the right, (X,Y) represent the Viewport coordinates which are obtained from <code>XF86VidModeGetViewPort</code>. The bright part is the part of the virtual screen which is visible on the monitor at that moment.
|
||||
|
||||
<h5><a name="talkMessageLog">Message log window</a></h5>
|
||||
<p>In all the applications up till now, error and other messages have been sent to stderr or stdout. when you start the programmes by (double-)clicking in your file manager, the messages may disappear, or pop up in a window. This makes starting the application from an xterm command line the most practical. To get rid of this disappointing feature, you can programme another window to send the messages to, or, more logically, use a named pipe to send them to a different application which you already have on your system. This section gives an example how to code this last method.
|
||||
</p><p>The method is simple: when the first message needs to be written, the code creates the pipe with <code>mknod</code>. If successful, it forks. The child process uses unix' <code>execlp</code> to start the logging application. In this example it is <kbd>xconsole</kbd>, with the pipe as its file argument. The parent process opens the pipe for writing. The application now can write to the pipe.
|
||||
</p><p>The first detail is in the function to close our applicaton, <code>closeAll</code>, in the examples. This function should terminate the child process, and also delete the file which was used for piping the data. The second detail is the way we keep track if the child process is still running, or whether the user has clicked it away. For this we declare a signal handler each time we start up the child process. At the SIGCHLD signal, which indicates the child process has been terminated, we call a function which deletes the pipe file as well, and sets a global variable to a value which allows us to check if the child process has terminated. When writing our second message, we check first if the child process is still running. If it is, we can write to the pipe, if it isn't, we create a new child process and pipe. If there is any problem, we fall back on the usual stderr. Here is the (extra) code for a simple implementation:
|
||||
|
||||
</p><pre><code>#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#define ERRMSGFIFO "/tmp/WINGsWindowfifo"
|
||||
#define NOLOGWINDOW (-2)
|
||||
#define FIFOERROR (-1)
|
||||
#define FIFOLOWESTPOSS 0
|
||||
|
||||
int fifonr=NOLOGWINDOW; /* the fifo nr, or an error value */
|
||||
int sibpid; /* the child's process ID */
|
||||
|
||||
|
||||
/* clean up when closing: */
|
||||
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
|
||||
WMDestroyWidget(self);
|
||||
if(--windowCounter<1){
|
||||
if (fifonr>=FIFOLOWESTPOSS)
|
||||
kill(sibpid,SIGTERM);
|
||||
if (!access(ERRMSGFIFO,F_OK|W_OK))
|
||||
unlink(ERRMSGFIFO);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* handle the case the child terminates. Set fifonr and clean up: */
|
||||
|
||||
void redirectmsg(int sig){
|
||||
|
||||
fifonr=NOLOGWINDOW;
|
||||
if (!access(ERRMSGFIFO,F_OK|W_OK))
|
||||
unlink(ERRMSGFIFO);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* have the log window pop up: */
|
||||
|
||||
int showMessageWindow(){
|
||||
|
||||
(void) signal(SIGCHLD,redirectmsg); /* use redirectmsg whenever the child process stops */
|
||||
|
||||
if(access(ERRMSGFIFO,F_OK)==-1)
|
||||
fifonr=mknod(ERRMSGFIFO,0640|O_EXCL|S_IFIFO,(dev_t)0);
|
||||
else
|
||||
fifonr=FIFOERROR;
|
||||
/* fifonr == FIFOERROR if mkfifo or access failed, for mknod returns -1 on failure */
|
||||
|
||||
if(fifonr!=FIFOERROR){
|
||||
|
||||
sibpid=fork();
|
||||
|
||||
if(sibpid==0){
|
||||
execlp("xconsole" , "xconsole", "-file",ERRMSGFIFO,"-geometry","250x400", \
|
||||
"-title","Application Messages",(char *)0);
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
fifonr=open(ERRMSGFIFO,O_WRONLY);
|
||||
}
|
||||
return fifonr;
|
||||
}
|
||||
|
||||
|
||||
/* usage: */
|
||||
|
||||
void someActionWithMessage(void *self, void *data){
|
||||
|
||||
if (fifonr<FIFOLOWESTPOSS)
|
||||
fifonr=showMessageWindow(); /* (re)start xconsole, or try again in case of FIFOERROR */
|
||||
|
||||
if (fifonr==FIFOERROR) /* if still error, use stderr */
|
||||
fprintf(stderr,"%s selected\n", WMgetSomeInformationFrom(self));
|
||||
else{
|
||||
char textbuffer[100];
|
||||
snprintf(textbuffer,99, "%s is the information\n", WMGetSomeInformationFrom(self));
|
||||
write(fifonr, textbuffer,strlen(textbuffer));
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>
|
||||
The <code>someActionWithMessage</code> function is a <a href="WINGStep2.html#WMAction">WMAction</a> in this case. Of course, there must be an xconsole in the user's path and he needs the correct rights. The example catches the events that the user clicks away the xconsole before he is finished, that the fifo file already exists, and that the fifo file is replaced with something which is not accessible during run time. There is nothing to change in <code>main</code>.
|
||||
|
||||
<br>
|
||||
</p><p>
|
||||
</p><table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGStep3.html">LAST: Step 3 Adding Widgets</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGGraphics.html">NEXT: Programming Details 2</a></td></tr></tbody></table>
|
||||
|
||||
|
||||
</body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
BIN
WINGs_tutorial/WINGsRemark_files/ScreenSize.jpeg
Normal file
|
After Width: | Height: | Size: 47 KiB |
64
WINGs_tutorial/WINGstep1.html
Normal file
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0074)WINGStep1.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="keywords" content="WINGs, tutorial, Introduction, C, programming, GUI, Window Maker, Linux">
|
||||
<meta name="description" content="WINGs library tutorial">
|
||||
<meta name="license" content="GNU Free Documentation License">
|
||||
<!-- <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGsIntro.html">LAST: Introduction</a></td> <td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGStep2.html">NEXT: Step 2 Processing Events</a></td></tr></tbody></table>
|
||||
|
||||
<h4>Step 1: Six lines show a window on the screen</h4>
|
||||
<p>
|
||||
The WINGs library allows you to get a window on the screen with a few lines of C-code. The following source code will give a non-responsive empty window. By adding a short function and just one extra line of code, we shall enable it to be closed by clicking the destroy button on the title bar.
|
||||
</p><h5>Application <a name="FirstWindow">FirstWindow</a></h5>
|
||||
<pre><code>#include <WINGs/WINGs.h>
|
||||
|
||||
int main (int argc, char **argv){
|
||||
|
||||
Display *display;
|
||||
WMScreen *screen;
|
||||
WMWindow *win;
|
||||
|
||||
display = XOpenDisplay("");
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
win = WMCreateWindow(screen, "");
|
||||
|
||||
WMRealizeWidget(win);
|
||||
WMMapWidget(win);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
}
|
||||
</code>
|
||||
</pre>
|
||||
<p>The order in which things are created is display -> screen -> window. A display is your pc, with keyboard and mouse. Its name is what you may see if you type into your xterm <code>echo $DISPLAY</code>. The answer might very well be:<kbd>:0.0</kbd>. Your PC may have more than one screen. So, after connecting to the display with <code>XOpenDisplay</code>, you must open a screen with <code>WMCreateScreen</code>. The display knows which screen is your default screen, and there is a function <code>Defaultscreen</code> to tell you that. Your application will need to open a window in that screen, and that window is what you would like to interact with.
|
||||
|
||||
You complete the window, and put it on the screen with <a name="WMMap"><code>WMMapWidget(WMWindow *window)</code></a>, and <code>WMRealizeWidget(WMWindow *window)</code>. Omitting either of these two functions, will have as result that your programme is stuck and you won't see anything on the screen. IN general, a widget is complete when <code>WMRealizedWidget</code>ed. As long as you do not map it, you will not see it. The other way round, it won't work. You cannot map a widget which has not been realized. After WMrealizing the window, you set the interface in motion by calling <code>WMScreenMainLoop(WMScreen *screen)</code>. <code>WMMapWidget</code> makes a widget visible. You can also <code>WMUnmapWidget</code> them.
|
||||
</p><p>The source code is <a href="FirstWindow.c">here</a>. There is an extra intialization line which organizes the data the WINGs functions work with. Compile it: The application will show a grey area inside of the borders which your window manager provides. If you started the programme by running ./FirstWindow from an xterm, you can stop it by using ctrl-c from the command line. If you started it in the graphical interface by double clicking it, you may or may not be able to close it with the close button on the title bar. You'll notice that in Windowmaker the button is disabled, and you need to kill the application (double click). If you are using a different window manager you <em>may</em> be able close the window by clicking on the close button. More about this in a <a href="WINGStep1.html#talkCloseWindow">moment</a>.
|
||||
|
||||
</p><h6>Setting some properties</h6>
|
||||
<p><em>After</em> creating the window with <code>WMCreatWindow</code>, and before mapping it, its <a name="WindowProps">properties</a> can be set. Function names speak for themselves.
|
||||
</p><ul><li><code>WMResizeWidget(WMWindow *window,size-t WinSizePixels,int WinSizePixels)</code>
|
||||
</li><li><code> WMSetWindowTitle(WMWindow *window, const char **titlestring)</code>
|
||||
</li><li><code> WMSetWindowMinSize(WMWindow *window,int s,int s)</code>
|
||||
</li><li><code> WMSetWindowAspectRatio(WMWindow *window,int t,int t, int t, size-t t)</code>
|
||||
</li><li><code> WMSetWindowResizeIncrements(WMWindow *window,int Size,int Size)</code>
|
||||
</li><li><code> WMSetWidgetBackgroundColor(WMWidget *window, WMColor *color)</code>
|
||||
</li></ul>
|
||||
A WMColor colour can be created and undone with
|
||||
<ul><li><code>WMColor * WMCreateRGBColor (WMScreen *screen, unsigned short red, unsigned short green, unsigned short blue, Bool exact)</code>
|
||||
</li><li><code>void WMReleaseColor (WMColor *color)</code>
|
||||
</li></ul>
|
||||
The resulting colour is a RGB combination..
|
||||
<p>After inserting whichever functions you like, compile the code again.
|
||||
|
||||
</p><h6><a name="talkMissing">Something is missing</a></h6>
|
||||
<p> Let us go back to the difference in <a name="talkCloseWindow">behaviour</a> under different window managers. Open an xterm, and run your application FirstWindow) from the command line <kbd>./FirstWindow</kbd>, that is, if it's in your current directory. We have seen that under windowmaker, the close button is disabled, and you can only close the window by using ctrl-c. Now switch to a different window manager, like xfce4 or (yes) fvwm2. Run FileName from the <em>command line</em> in an xterm. Click on the close button in the title bar. The window closes, but that is not all. You are getting an error message in your xterm, when you close the window. xfce4 says <kbd>Broken pipe</kbd>. fvwm has more funky messages like <kbd>XIO: fatal IO error 104 (Connection reset by peer) on X server ":0.0" after 1320 requests (1319 known processed) with 1 events remaining.</kbd>, or <kbd>X connection to :0.0 broken (explicit kill or server shutdown)</kbd>. So one window manager disables a button, and the others give error messages. We have a problem to solve in any of them.
|
||||
|
||||
</p><table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGsIntro.html">LAST: Introduction</a></td> <td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGStep2.html">NEXT: Step 2 Processing Events</a></td></tr></tbody></table>
|
||||
|
||||
|
||||
</body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
59
WINGs_tutorial/WINGstep2.html
Normal file
@@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0074)WINGStep2.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="keywords" content="WINGs, tutorial, Introduction, C, programming, GUI, Window Maker, Linux">
|
||||
<meta name="description" content="WINGs library tutorial">
|
||||
<meta name="license" content="GNU Free Documentation License">
|
||||
<!-- <META http-equiv="Content-Type" content="text/html> -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGStep1.html">LAST: Step 1 Drawing a Window</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGStep3.html">NEXT: Step 3 Adding Widgets</a></td></tr></tbody></table>
|
||||
|
||||
<h4>Step 2: Processing events</h4>
|
||||
|
||||
<h5>Closing the window</h5>
|
||||
|
||||
<p>Every widget can process <a name="talkEvents">events</a> if it wants to. An event is a structure with information, which is created by the X-server, when certain things happen, such as a mouse click, a pressed key, or the raising of a window. These Xevents are queued. You can select for a window or widget, which events, sent by the X-server, you want it to use. The other events will be ignored. The widget takes these events out of the queue. You must specify which function will be executed for which event. In our FirstWindow application, we have not done anything of this kind.
|
||||
|
||||
</p><p>In the FirstWindow application, the <code>WMScreenMainLoop(screen)</code> call puts the application into a loop to wait for events. We had not specified any events to be processed, however, and the application does not react to the event that you told the window manager to close it by clicking on the close button. For this, there is an easy fix. It is the <a name="WindowCloseAction">function</a>
|
||||
<br><code>void WMSetWindowCloseAction (WMWindow *window, WMAction *action, void *clientData)</code><br>
|
||||
This should be called after the window's creation and before its mapping with <code>WMMapWidget()</code>. The argument <a name="WMAction"><code>WMAction</code></a> must be a function, which looks like this:<br><code>void action(WMWidget *self,void *data){ commands}</code>.<br> It is automatically called when the window is closed. Typically, it handles the data, it destroys the widget where the CloseAction event arrived, in this case our only window. In our simple programme, we would simply exit the application. If there can be more than a single window, we should keep track of their number, and exit only if we are on the last window (if we wish to do so). Widgets are deleted by <code>void WMDestroyWidget (WMWidget *widget)</code> Now , to the <a href="WINGStep1.html#FirstWindow">FirstWindow</a> code, we can, somewhere before the <code>main</code> function, define this function:
|
||||
</p><pre><code>
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
WMDestroyWidget(self);
|
||||
fprintf(stderr, "I've been used!\n");
|
||||
exit(0);
|
||||
}
|
||||
</code></pre>
|
||||
We write a message to the standard error output when the function is used. After the <code>WMCreateWindow()</code> line, we insert the line:
|
||||
<pre><code>WMSetWindowCloseAction(window, closeAll, NULL);</code></pre>
|
||||
<p><img src="./WINGstep2_files/FirstWindow.jpeg" align="right">Compile it. The source code now looks like <a href="SecondWindow.c">this</a>. Do the experiments <a href="WINGStep1.html#talkCloseWindow">above</a> again. In Windowmaker the close button now is enabled. In the other window managers, the error messages have disappeared, and our function lets us know it has been used.
|
||||
The title bar reads "untitled", because we have not used <code>WMSetWindowTitle</code>. The destroy-button now is enabled, however. The colour was created by the red, green, and blue values : <code>124<<9, 206<<8</code>, and <code>162<<8</code>.
|
||||
|
||||
|
||||
</p><h5>Closing the window in a different way</h5>
|
||||
The <code>WMSetWindowCloseAction()</code> hides many details. Suppose we like to close the window and end the application in a different way. We can use the same <code>closeAll</code> function as above for this. We are going to close the window whenever there is a mouse click in it. When there is a click, the system notifies the window that there is an X-event "ButtonPress". To use this, we must specify which events we want to use for the window, and specify which function will be called in case such an event arrives. The function to do this, is <br><code> void WMCreateEventHandler (WMView *view, unsigned long mask, WMEventProc *eventProc,void *clientData)</code>.<br> The <var>mask</var> argument in it will be an "OR"ed combination of masks. <a href="WINGLib.html#EventsList">Here</a> is a list of Events and their event masks. For the moment, we just need "ButtonPressMask". The WMEventProc is a function which must look like <code>void eventProc(XEvent *event, void *data)</code>. The clientData is our window to which we like to give access for these events. (WMView *) is a member in the WMWidget structure. It can be obtained from the window by the function <code> WMWidgetView(WMWindow *window)</code>.
|
||||
Now, insert the following function after our closeAll function in the programme
|
||||
<pre><code>
|
||||
static void handleEvents(XEvent *event, void *data)
|
||||
{
|
||||
WMWidget *widget = (WMWidget*)data;
|
||||
switch (event->type) {
|
||||
case ButtonPress:
|
||||
closeAll(widget,NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
It says that if the incoming event for the window is of type ButtonPress, it will call the function closeAll. We really do not need the switch statement now, because we do not specify anything for <code>ButtonRelease</code>. Usually we define functions for all the event types which we have specified by the mask in the WMCreateEventHandler function. Now, after the line with <code>WMCreateWindow()</code>, insert the following line in our programme:
|
||||
<br><pre><code> WMCreateEventHandler(WMWidgetView(win), ButtonPressMask,handleEvents, win)</code></pre>
|
||||
The full source code now looks like <a href="ThirdWindow.c">this</a>. Compile the code. Run the programme, and find that the window closes as soon as you click in it. We have given window access to the ButtonPress Xevent, and specified that in case this event comes up, the closeAll function should be called. We'll remove this annoying feature again in the next step, when we shall show a button in the window, which will duely close the window when clicked.
|
||||
|
||||
<br>
|
||||
<p>
|
||||
</p><table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGStep1.html">LAST: Step 1 Drawing a Window</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGStep3.html">NEXT: Step 3 Adding Widgets</a></td></tr></tbody></table>
|
||||
|
||||
|
||||
</body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
BIN
WINGs_tutorial/WINGstep2_files/FirstWindow.jpeg
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
143
WINGs_tutorial/WINGstep3.html
Normal file
@@ -0,0 +1,143 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0074)WINGStep3.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="keywords" content="WINGs, tutorial, GUI, Window Maker, widget, Linux">
|
||||
<meta name="description" content="WINGs library tutorial">
|
||||
<meta name="license" content="GNU Free Documentation License">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGStep2.html">LAST: Step 2 Processing Events</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGsRemark.html">NEXT: Programming Details</a></td></tr></tbody></table>
|
||||
|
||||
<h4>Step 3: Adding widgets to a window</h4>
|
||||
|
||||
<h5>Adding buttons to a widget</h5>
|
||||
<p>As a window is a widget, we can create a button for it with the function<br>
|
||||
<code> WMButton * WMCreateButton (WMWidget *parent, WMButtonType type)</code><br>
|
||||
To make the button visible, the function <code>WMMapSubwidgets</code> may be called on the window. A call to WMMapWidget on the button will do the same of course. Before mapping the button, its properties can be set with functions whose names speak for themselves
|
||||
|
||||
</p><p>
|
||||
</p><ul><li><code> void WMSetButtonText (WMButton *bPtr, char *text)</code>
|
||||
</li><li><code>void WMSetButtonTextAlignment (WMButton *bPtr,WMAlignment alignment)</code>
|
||||
</li><li><code> void WMSetButtonAction (WMButton *bPtr, WMAction *action, void *clientData)</code>
|
||||
</li><li><code> void WMMoveWidget (WMWidget *wdiget, int pixelstoright, int pixelsdown)</code>
|
||||
</li><li><code> WMScreen * WMWidgetScreen (WMWidget *widget)</code>
|
||||
</li><li><code> WMSize WMGetViewSize (WMView *view)</code>
|
||||
</li><li><code>void WMMapSubwidgets (WMWidget *widget)</code>
|
||||
</li></ul>
|
||||
|
||||
<p>As windows and buttons are both widgets, <code>WMResizeWidget()</code> is the same as for the window <a href="WINGStep1.html#WindowProps">above</a>, just as the function to set the background colour. Sizing and moving is in pixels, movements are in pixels from the parent widget's upper left corner. The default action on a button, which is a mouse click, will call the WMAction function, just as happens with the <a href="WINGStep2.html#WindowCloseAction">CloseAction</a> on the window. WMAlignment can be WALeft, WACenter, WARight or WAJustified.
|
||||
|
||||
</p><p>The different WMButtonTypes are <img src="./WINGstep3_files/Buttons.jpeg" align="right">
|
||||
</p><dl><dt>Touch buttons:</dt><dd><code>WBTMomentaryPush, WBTMomentaryChange,WBTMomentaryLight </code>
|
||||
</dd><dt>Alternate on/off buttons: </dt><dd><code>WBTPushOnPushOff, WBTOnOff, WBToggle</code>
|
||||
</dd><dt>Checkbox with label next to it:</dt><dd> <code>WBTSwitch, WBTRadio</code>
|
||||
</dd></dl>
|
||||
Particular behaviour of a button can be obtained by using the function<br>
|
||||
<code>WMButton * WMCreateCustomButton (WMWidget *parent, int behaviourMask)</code><br>
|
||||
By default a new widget will be placed in the window's top left corner. <code>WMMoveWidget</code> is used to place it correctly.
|
||||
<p>Buttons can be grouped together by using a WMBox widget. You would do this when you want to do something fancy with the buttons, eg. filling the width of a part of the window, and resizing with that part. Create the box before creating the button, WMMap the button, and next add the latter's view, extracted with WMWidgetView() to the box:
|
||||
</p><ul>
|
||||
<li><code>WMBox * WMCreateBox (WMWidget *parent)</code>
|
||||
</li><li><code> void WMSetBoxHorizontal (WMBox *box, Bool TrueorFalse)</code>
|
||||
</li><li><code> void WMAddBoxSubview (WMBox *box, WMView *buttonsview,
|
||||
Bool expand, Bool fill, int minSize,
|
||||
int maxSizeor0, int space)</code>
|
||||
</li><li><code>void WMSetBoxBorderWidth (WMBox *box, unsigned width)</code>
|
||||
</li><li><code>void WMSetViewExpandsToParent (WMView *boxview, int leftOffset,
|
||||
int topOffset, int rightOffset,
|
||||
int bottomOffset)</code>
|
||||
</li></ul>
|
||||
<p>In the <code>WMAddBoxSubview</code> function, setting expand to True will stretch the button to the height of the box. <code>space</code> sets the space after the button. To resize the widgetbox with the window, you can use the <code>WMSetViewExpandsToParent</code> function. Otherwise, you can calculate your own positions, and move the box to where it is supposed to be in a resized window. There are other ways to group buttons, or other widgets, eg. by a <a href="WINGStep3.html#talkFrame">frame</a>.
|
||||
|
||||
</p><h6>Resize events</h6>
|
||||
To know the current window's size, and the size of any other widget, there is the function <code> WMSize WMGetViewSize (WMView *view)</code>. As before, the function <code>WMWidgetView</code> casts the widget into a view. <code>WMWidgetScreen</code> returns a pointer to the screen in which the widget was created.
|
||||
|
||||
<p>We thus can get the window's size, and place widgets in their correct positions. What is left to do is a function which handles the event that the user resizes the window. The buttons, or the box containing them, should move to their correct positions in the window again in such an event, or resize with the window itself. There is an event <code>WMViewSizeDidChangeNotification</code> when the window is resized. For a WMWindow win, passing WMWidgetView(win) as the last argument to the function below will define what to do when this event occurs.
|
||||
<br><code> void WMAddNotificationObserver (WMNotificationObserverAction *observerAction, void *observer,const char *name, void *object)</code><br>
|
||||
The third argument should be the event's name (WMViewSizeDidChangeNotification), and the first argument is the name of the function which will be called. This function should look like <code>void observerAct(void *self, WMNotification *notification)</code>. It is all done in the sample code <a href="FourthWindow.c">here</a>.
|
||||
|
||||
</p><h6>Adding the event handlers and widgets to the application</h6>
|
||||
In the FirstWindow code, we insert the following lines to handle the resize notification:<br>
|
||||
<pre><code> WMSetViewNotifySizeChanges(WMWidgetView(win), True);
|
||||
WMAddNotificationObserver(resizeHandler, NULL, WMViewSizeDidChangeNotification, WMWidgetView(win));</code></pre>
|
||||
<p>Before the <code>main</code> function we define the function (<code>resizeHandler</code>) which will handle the resize event for the two widgets, the text area and the box with buttons. There is a global variable ButtonsetSize, which contains the size of the box with buttons:
|
||||
</p><pre><code> WMSize ButtonsetSize;
|
||||
static void resizeHandler(void *self, WMNotification *notif){
|
||||
WMSize size = WMGetViewSize(WMWidgetView(win));
|
||||
WMMoveWidget(box, size.width-ButtonsetSize.width, size.height-ButtonsetSize.height);
|
||||
WMResizeWidget(text, size.width-MARGIN -10, size.height-80);
|
||||
}
|
||||
static void handleEvents(XEvent *event, void *data)
|
||||
{int i=0;
|
||||
WMWidget *widget = (WMWidget*)data;
|
||||
switch (event->type) {
|
||||
case ButtonPress:
|
||||
while (i<40)textbuf[i++]=' ';
|
||||
snprintf(textbuf,39,"Button down at (%i,%i) \n-",event->xbutton.x,event->xbutton.y);
|
||||
WMFreezeText(text);
|
||||
WMAppendTextStream(text,textbuf);
|
||||
WMThawText(text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
</code></pre>
|
||||
The buttons keep their size, but are moved to stay in the bottom right corner, the text area is resized along with the window, but stays 80 pixels away from the window bottom border. We also do something useful with the mouseclicks on the window itself. This is done in the function handleEvents. The event ButtonPress has the click time and position in a member <code>.xbutton</code>. When the button is pressed, we get that information, and print it to the text area.
|
||||
|
||||
<p> The text is written to a <a href="WINGLib.html#TextArea">text area</a>. Function names for it are self-explanatory. We create this widget after creating the window. It will be WMmapped by the final <code>WMMapSubwidgets</code>. The code for setting it up is just:
|
||||
</p><pre><code> text = WMCreateText(win);
|
||||
WMResizeWidget(text, WINWIDTH-MARGIN, WINHEIGHT -80);
|
||||
WMMoveWidget(text, 10, 10)</code></pre>The text is written to the area by passing character strings to the <code>WMAppendTextStream</code> function.
|
||||
|
||||
<p>The important functions in creating the box and its widgets are:
|
||||
</p><pre><code> box=WMCreateBox(win);
|
||||
WMSetBoxBorderWidth(box, MARGIN);
|
||||
WMSetBoxHorizontal(box, True);
|
||||
Button =WMCreateButton(box,WBTMomentaryPush);
|
||||
WMSetButtonAction (Button, selectFiles, NULL);
|
||||
WMMapWidget(Button);
|
||||
ButtonsetSize = WMGetViewSize(WMWidgetView(QuitButton));
|
||||
WMAddBoxSubview(box, WMWidgetView(QuitButton), True,False, 60, 1000, MARGIN);
|
||||
/*-- make and add another button --*/
|
||||
WMResizeWidget(box, 4*MARGIN+2*ButtonsetSize.width,2*MARGIN+ButtonsetSize.height);
|
||||
ButtonsetSize =WMGetViewSize(WMWidgetView(box));
|
||||
resizeHandler(NULL,NULL)</code></pre>
|
||||
<img src="./WINGstep3_files/FirstWindow4.jpeg" align="LEFT" alt="Application window" hspace="#5">The box is created before the button is, because the button will have to be created with the box (its parent widget) as its first argument. The box is the "outer" widget and will be mapped with <code>WMMapSubwidgets</code>, but we map the buttons separately. The function which will be called on the default button event is closeAll() for the quit button. The file button will call the <code>selectFiles()</code> function, in which we open a <a href="WINGLib.html#FileSelect">file selector</a> widget. We have left it to WINGs to decide what size the button will be. We temporarily use ButtonsetSize to store this size. We add the button's view to the box. After adding all the buttons, We store the size of the resulting box, and use it in our <kbd>resizeHandler</kbd> function to keep the box in the corner. <img src="./WINGstep3_files/OpenFileDialog.jpeg" align="Right" width="20%" alt="File selector widget" hspace="#5">.Following the <a href="FourthWindow.c">source code</a>, pressing the file button will pop up the file selector dialog, and the name of the selected file is printed in the text area. Notice that, without the box widget, we would need two global Button pointers to change the position of both buttons in the <kbd>resizeHandler</kbd> function. We now need one Button pointer, which can remain local to <code>main</code>.
|
||||
|
||||
<p><a href="FourthWindow.c">Here</a> is the full code which we have now. As we have a text area, we can print text to it, as long as we are sure that the widget has not been destroyed. The scroll bar next to the area is obtained with one single <a href="WINGLib.html#TextArea">function</a> call.
|
||||
|
||||
</p><h6>Frames</h6>
|
||||
<p>The WMBox needs quite some configuration. It is not really intended for putting two simple buttons in a corner. We can use a <a name="talkFrame"></a><a href="WINGLib.html#Frames">frame</a> to keep widgets together and move them with one single pointer. For buttons, we could also use the <code>WMGroupButtons</code> function to handle a group of buttons with just one pointer. To use a frame, use this code, instead of the WMBox functions: At global scope:
|
||||
</p><pre><code>WMFrame *controlframe;
|
||||
static void resizeHandler(void *self, WMNotification *notif){
|
||||
WMSize size = WMGetViewSize(WMWidgetView(win));
|
||||
WMMoveWidget(controlframe, size.width-ButtonsetSize.width, size.height-ButtonsetSize.height);
|
||||
WMResizeWidget(text, size.width-MARGIN -10, size.height-80);
|
||||
}</code></pre>
|
||||
In <code>main</code>:
|
||||
<pre><code> controlframe=WMCreateFrame(win);
|
||||
Button =WMCreateButton(controlframe,WBTMomentaryPush);
|
||||
ButtonsetSize = WMGetViewSize(WMWidgetView(Button));
|
||||
WMMoveWidget(Button,MARGIN, MARGIN);
|
||||
/* (code to create a second button of the same size, with the same pointer) */
|
||||
WMMoveWidget(Button,2*MARGIN+ButtonsetSize.width, MARGIN);
|
||||
ButtonsetSize.width = 3*MARGIN+2*ButtonsetSize.width;
|
||||
ButtonsetSize.height=2*MARGIN+ButtonsetSize.height;
|
||||
WMResizeWidget(controlframe,ButtonsetSize.width,ButtonsetSize.height);
|
||||
WMMapSubwidgets(controlframe);</code></pre>
|
||||
|
||||
<p>As we created the buttons inside the frame, we WMMoveWidget them along coordinates with respect to the frame's upper left corner. We have left it to WINGs to set the buttons' size, so we get their size with <code>WMGetViewSize</code>. With the button sizes, we calculate what size the frame is to have, and how far we need to move the buttons from the upper left corner to get them to the right place. We WMMap both buttons inside the frame with <code>WMMapSubwidgets(controlframe);</code>. The frame is the outer widget, and will be WMMapped just before the window. Replacing the box with the frame, we get <a href="FifthWindow.c">this</a> source code. After compiling, we get the same application. The obvious frame properties are set with the <a href="WINGLib.html#Frames">frame functions</a>
|
||||
|
||||
</p><h5>Next sections</h5>
|
||||
<p> The three steps up till now have shown the important points in programming with the WINGs library. The basics are all the same all the time. Create, specify WMAction, define the WMAction function somewhere, WMMap the widget. If this won't do, use <a href="WINGLib.html#Notification">PostNotification</a>, and <code>AddNotificationObserver</code> to the widget which should react to it.
|
||||
</p><p>From the next sections, the <a href="WINGLib.html">library description</a> gives a whole range of widgets which you can fit into the window this way, and related functions and data structures. There is sample code for those widgets whose code seems a bit more involved. The only thing which cannot be obtained by a simple function call is a menu with submenus, which is to work under any window manager, not just Window Maker. The <a href="WINGMenu.html">third programming detail section</a> explains, how to programme this kind of menu. The other two programming detail sections are not about the WINGs/wraster/windowmaker libraries themselves, except for a <a href="WINGsRemark.html#talkIcons">short section</a> on the use of the WINGs functions to insert icons into widgets. Detail <a href="WINGsRemark.html">section 1</a> contains an <a href="WINGsRemark.html#talkMessageLog">example</a> of how to get rid of the disappointing xterm window which you need to start your windowed application from, to read its messages on stderr or stdout. It shows the standard code to open a <a href="WINGsRemark.html#talkMessageLog">logging window</a> on the screen when needed. For convenience, it uses xconsole for this, a standard application on unix systems with X11. The same section 1 shows how to get the correct information about <a href="WINGsRemark.html#talkResolution">monitor resolution</a> when a virtual screen is used. Detail <a href="WINGGraphics.html">section 2</a> gives code samples which demonstrate how to mix Xlib code with the WINGs library. Xlib is the library which gives direct access to the X-server, and which is the underlying code to the WINGs library itself. It also contains a <a href="WINGGraphics.html#talkOpenGL"> section</a> which shows how to use OpenGL 3D graphics code in a WINGs frame. These extra sections do not explain all the details on the used libraries. However, by just following the code examples, you can reproduce their results, and change them to use them in your own programmes.
|
||||
|
||||
|
||||
<br>
|
||||
</p><p>
|
||||
</p><table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"><a href="WINGStep2.html">LAST: Step 2 Processing Events</a></td><td align="CENTER"><a href="WINGtoc.html">Contents</a></td><td align="RIGHT"><a href="WINGsRemark.html">NEXT: Programming Details</a></td></tr></tbody></table>
|
||||
|
||||
|
||||
</body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
BIN
WINGs_tutorial/WINGstep3_files/Buttons.jpeg
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
WINGs_tutorial/WINGstep3_files/FirstWindow4.jpeg
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
WINGs_tutorial/WINGstep3_files/OpenFileDialog.jpeg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
WINGs_tutorial/WINGstep3_files/ScreenSize.jpeg
Normal file
|
After Width: | Height: | Size: 47 KiB |
126
WINGs_tutorial/WINGtoc.html
Normal file
@@ -0,0 +1,126 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- saved from url=(0072)WINGtoc.html -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3 Steps to Make a WINGs User Interface</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="keywords" content="WINGs, tutorial, Introduction, C, programming, GUI, Window Maker, Linux">
|
||||
<meta name="description" content="WINGs library tutorial">
|
||||
<meta name="license" content="GNU Free Documentation License">
|
||||
|
||||
<!-- <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align="JUSTIFY" width="100%"><tbody><tr><td align="LEFT"></td><td align="RIGHT"><a href="WINGsIntro.html">NEXT: Introduction</a></td></tr></tbody></table>
|
||||
<h2>A WINGs based graphical user interface in three steps</h2>
|
||||
<h3>CONTENTS</h3>
|
||||
<ol>
|
||||
<li><a href="WINGsIntro.html">Introduction</a>
|
||||
</li><li><a href="WINGstep1.html"><strong>Step 1.</strong> Six lines show a window on the screen </a>
|
||||
<ol>
|
||||
<li>First application
|
||||
</li><li>Setting properties
|
||||
</li><li>Something is missing
|
||||
</li></ol>
|
||||
</li><li><a href="WINGstep2.html"><strong>Step 2.</strong> Processing events</a>
|
||||
<ol><li>Closing the window
|
||||
</li><li>Closing the window in a different way
|
||||
</li></ol>
|
||||
</li><li><a href="WINGstep3.html"><strong>Step 3.</strong> Adding widgets to a window</a>
|
||||
<ol><li>Adding buttons to a widget
|
||||
</li><li>Resize events
|
||||
</li><li>Adding the event handlers and widgets to the application
|
||||
</li><li>Frames
|
||||
</li></ol>
|
||||
</li><li><a href="WINGsRemark.html">Programming details</a>
|
||||
<ol><li>Count the windows
|
||||
</li><li>Icons and images
|
||||
</li><li>Virtual screen and resolution
|
||||
</li><li>Message log window
|
||||
</li></ol>
|
||||
</li><li><a href="WINGGraphics.html">Graphics programming details</a>
|
||||
<ol><li>The Drawable
|
||||
</li><li>Xlib Graphics Functions
|
||||
</li><li>An OpenGL Drawing Area
|
||||
</li></ol>
|
||||
</li><li><a href="WINGMenu.html">Floating hierarchical menus</a>
|
||||
<ol><li>The menu widget
|
||||
</li><li>Window Manager Hints</li></ol>
|
||||
</li><li><a href="WINGLib.html">Complete library description</a>
|
||||
<ol><li>General widgets
|
||||
</li><li>Frames
|
||||
</li><li>Panels
|
||||
</li><li>Windows
|
||||
</li><li>Views
|
||||
</li><li>Buttons
|
||||
</li><li>Button boxes
|
||||
</li><li>Expanding and pull-down buttons
|
||||
</li><li>Text fields
|
||||
</li><li>Labels
|
||||
</li><li>Sliders
|
||||
</li><li>Scrollable views
|
||||
</li><li>Message pop-up windows
|
||||
</li><li>Input dialogs
|
||||
</li><li>File selection dialogs
|
||||
</li><li>Text Areas
|
||||
</li><li>Split windows/views
|
||||
</li><li>Lists
|
||||
</li><li>Colour selection panels
|
||||
</li><li>Font selection panel
|
||||
</li><li>Tabbed views
|
||||
</li><li>Progress indicators
|
||||
</li><li>Event handlers
|
||||
</li><li>Selections
|
||||
</li><li>Screens
|
||||
</li><li>Image functions
|
||||
</li><li>Application wide functions
|
||||
</li><li>Notifications
|
||||
</li><li>Text balloons
|
||||
</li><li>Drag/drop functions
|
||||
</li><li>Network connections
|
||||
</li><li>Draw functions
|
||||
</li><li>Browser functions
|
||||
</li><li>Menu items
|
||||
</li><li>Utilities/redefined functions
|
||||
</li><li>Data types
|
||||
<ol><li>WMColor
|
||||
</li><li>WMFont
|
||||
</li><li>WMArray
|
||||
</li><li>Trees
|
||||
</li></ol>
|
||||
</li><li>ENUMs and #defines
|
||||
<ol><li>List of event masks and corresponding events
|
||||
</li><li> Frame Title Positions
|
||||
</li><li> WM Image Positions
|
||||
</li><li>WMAlignment
|
||||
</li><li>Reliefs
|
||||
</li></ol></li></ol>
|
||||
</li><li>Appendix: list of examples<ol>
|
||||
<li><a href="FirstWindow.c">Minimal window</a>
|
||||
</li><li><a href="SecondWindow.c">Responsive window</a>
|
||||
</li><li><a href="ThirdWindow.c">Clickable window</a>
|
||||
</li><li><a href="FourthWindow.c">Window with buttons and text area</a>
|
||||
</li><li><a href="FifthWindow.c">Window with buttons and text area using frames</a>
|
||||
</li><li><a href="SixthWindow.c">Pixmap drawing</a>
|
||||
</li><li><a href="SeventhWindow.c">Xlib drawing</a>
|
||||
</li><li><a href="EighthWindow.c">Menu creation</a>
|
||||
</li><li><a href="NinthWindow.c">Menu and submenus</a>
|
||||
</li><li><a href="glframe.c">OpenGL in a frame</a>
|
||||
</li></ol>
|
||||
</li><li><small><a href="FDL.html">GNU Free Documentation License</a></small>
|
||||
</li></ol>
|
||||
<p>
|
||||
</p><p>
|
||||
<br>
|
||||
<br>
|
||||
<tiny><small> Copyright (c) 2010
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, with no
|
||||
Front-Cover Texts, and with no Back-Cover Texts.
|
||||
A copy of the license is included in the section entitled <a href="FDL.html">"GNU
|
||||
Free Documentation License"</a>.</small></tiny>
|
||||
|
||||
|
||||
|
||||
</p></body><style type="text/css">embed[type*="application/x-shockwave-flash"],embed[src*=".swf"],object[type*="application/x-shockwave-flash"],object[codetype*="application/x-shockwave-flash"],object[src*=".swf"],object[codebase*="swflash.cab"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"],object[classid*="d27cdb6e-ae6d-11cf-96b8-444553540000"],object[classid*="D27CDB6E-AE6D-11cf-96B8-444553540000"]{ display: none !important;}</style></html>
|
||||
283
WINGs_tutorial/glframe.c
Normal file
@@ -0,0 +1,283 @@
|
||||
#include <X11/keysym.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <WINGs/WINGs.h>
|
||||
#include <WINGs/WINGsP.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define CONTENTH 300
|
||||
#define CONTENTW 300
|
||||
#define CONTENTMARGIN 30
|
||||
|
||||
|
||||
struct couple{
|
||||
WMWindow *window;
|
||||
WMFrame *frame;
|
||||
} datacouple;
|
||||
|
||||
|
||||
float red=252.0/256, green=88.0/256, blue=16.0/256;
|
||||
float redb=252.0/256, greenb=242.0/256, blueb=80.0/256;
|
||||
|
||||
int Attr[] = { GLX_RGBA,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 16,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None};
|
||||
Display * display;
|
||||
float alpha=0;
|
||||
|
||||
void init(void)
|
||||
{
|
||||
glClearColor (256/256, 256/256, 256/256, 0.0);
|
||||
glPolygonMode(GL_FRONT, GL_FILL);
|
||||
glPolygonMode(GL_BACK, GL_FILL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
|
||||
GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
GLfloat position[] = { 2.0f, -0.1f, 2.0f, 1.0f };
|
||||
GLfloat position2[] = { -2.0f, -0.26f, -4.0f, 1.0f };
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
|
||||
//glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
|
||||
glMateriali(GL_FRONT, GL_SHININESS, 98);
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, position2);
|
||||
//glLightfv(GL_LIGHT1, GL_POSITION, position2);
|
||||
|
||||
glEnable(GL_LIGHT0);
|
||||
//glEnable(GL_LIGHT1);
|
||||
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
||||
//glColorMaterial(GL_FRONT, GL_SPECULAR);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glCullFace( GL_BACK );
|
||||
glEnable( GL_CULL_FACE );
|
||||
|
||||
glEnable(GL_POLYGON_SMOOTH);
|
||||
/*glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);*/
|
||||
|
||||
}
|
||||
|
||||
void normvector(float a, float aa, float aaa, float b, float bb, float bbb, float c, float cc, float ccc,float *result){
|
||||
float v1[3];float v2[3];float tmp;
|
||||
|
||||
v1[0]=(b-a);v1[1]=(bb-aa);v1[2]=(bbb-aaa);
|
||||
v2[0]=(b-c);v2[1]=(bb-cc);v2[2]=(bbb-ccc);
|
||||
result[0]=(v1[1]*v2[2]-v1[2]*v2[1]);
|
||||
result[1]=(v1[2]*v2[0]-v1[0]*v2[2]);
|
||||
result[2]=(v1[0]*v2[1]-v1[1]*v2[0]);
|
||||
tmp=sqrt(result[0]*result[0]+result[1]*result[1]+result[2]*result[2]);
|
||||
result[0]/=tmp;
|
||||
result[1]/=tmp;
|
||||
result[2]/=tmp;
|
||||
}
|
||||
|
||||
|
||||
void redraw(XEvent * v,void *xw){
|
||||
Window win;
|
||||
float z[3];
|
||||
|
||||
win = *(Window *)xw;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
glPushMatrix(); glShadeModel(GL_SMOOTH);
|
||||
|
||||
glRotatef(alpha, 0, 1, 0);
|
||||
if (alpha > 360) alpha =alpha-360;
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
||||
glColor3f(redb,greenb,blueb);
|
||||
normvector(-0.85f, 0.0f, 0.0f,0.0f, 0.0f, 0.85f,0.0f, 0.6f, 0.0f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(-0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, 0.85f);
|
||||
glVertex3f(0.0f, 0.6f, 0.0f);
|
||||
|
||||
normvector(0.0f, 0.0f,0.85f,0.85f, 0.0f, 0.0f,0.0f, 0.60f,0.0f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.0f, 0.0f, 0.85f);
|
||||
glVertex3f(0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.6f, 0.0f);
|
||||
|
||||
glColor3f(red,green,blue);
|
||||
normvector(0.85f, 0.0f, 0.0f,0.0f, 0.0f, -0.85f,0.0f, 0.6f, 0.0f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, -0.85f);
|
||||
glVertex3f(0.0f, 0.6f, 0.0f);
|
||||
|
||||
normvector(0.0f, 0.0f, -0.85f,-0.85f, 0.0f, 0.0f,0.0f, 0.6f, 0.0f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.0f, 0.0f, -0.85f);
|
||||
glVertex3f(-0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.6f, 0.0f);
|
||||
|
||||
glColor3f(redb,greenb,blueb);
|
||||
normvector(-0.85f, 0.0f, 0.0f,0.0f, -1.0f, 0.0f,0.0f, 0.0f, 0.85f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(-0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, -1.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, 0.85f);
|
||||
|
||||
normvector(0.0f, 0.0f, 0.85f, 0.0f, -1.0f, 0.0f,0.85f, 0.0f, 0.0f ,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.0f, 0.0f, 0.85f);
|
||||
glVertex3f(0.0f, -1.0f, 0.0f);
|
||||
glVertex3f(0.85f, 0.0f, 0.0f);
|
||||
|
||||
glColor3f(red,green,blue);
|
||||
normvector(0.85f, 0.0f, 0.0f,0.0f, -1.0f, 0.0f, 0.0f, 0.0,-0.85f ,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f,-1.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, -0.85f);
|
||||
|
||||
normvector(0.0f, 0.0f, -0.85f,0.0f, -1.0f, 0.0f, -0.85f, 0.0f,0.0f ,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.0f, 0.0f, -0.85f);
|
||||
glVertex3f(0.0f, -1.0f, 0.0f);
|
||||
glVertex3f(-0.85f, 0.0f, 0.0f);
|
||||
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
glXSwapBuffers(display, win);
|
||||
}
|
||||
|
||||
setsize(unsigned int width, unsigned int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
}
|
||||
|
||||
void DoRotate(void *self,void *xwindow){
|
||||
XEvent event;int i=0;
|
||||
alpha+=15;
|
||||
redraw(NULL,(Window *)xwindow);
|
||||
}
|
||||
|
||||
void redo(XEvent * event,void *xw){
|
||||
switch (event->type)
|
||||
{
|
||||
case Expose:
|
||||
if (event->xexpose.count!=0) break;
|
||||
redraw(event,&event->xexpose.window);
|
||||
break;
|
||||
case ConfigureNotify: setsize(event->xconfigure.width, event->xconfigure.height); // assuming there will be an expose afterwards
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
WMDestroyWidget(self);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void resizeHandler(void *data, WMNotification *notif){
|
||||
struct couple *tmp;tmp=(struct couple *)data;
|
||||
WMSize size = WMGetViewSize(WMWidgetView(tmp->window));
|
||||
WMResizeWidget(tmp->frame, size.width -2*CONTENTMARGIN, size.height-2*CONTENTMARGIN);
|
||||
}
|
||||
|
||||
void getargs(int argc, char **argv){
|
||||
if (argc>3) {
|
||||
redb=red=(float)atoi(argv[1])/256;
|
||||
greenb=green=(float)atoi(argv[2])/256;
|
||||
blueb=blue=(float)atoi(argv[3])/256;
|
||||
}
|
||||
if (argc>6){
|
||||
redb=(float)atoi(argv[4])/256;
|
||||
greenb=(float)atoi(argv[5])/256;
|
||||
blueb=(float)atoi(argv[6])/256;
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char **argv){
|
||||
|
||||
WMFrame *glframe;
|
||||
WMScreen *screen;
|
||||
WMWindow *window;
|
||||
WMButton *Button;
|
||||
|
||||
|
||||
/* Xlib and glX variables */
|
||||
Window win;
|
||||
XVisualInfo *xvVisualInfo;
|
||||
Colormap cmColorMap;
|
||||
XSetWindowAttributes winAttr;
|
||||
GLXContext glXContext;
|
||||
|
||||
getargs(argc,argv);
|
||||
WMInitializeApplication("GLWindow", &argc, argv);
|
||||
display = XOpenDisplay("");
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
|
||||
if(!glXQueryExtension(display, NULL, NULL)){wwarning("X server does not have GLX\n"); return 0; }
|
||||
|
||||
window = WMCreateWindow(screen, "Main");
|
||||
WMResizeWidget(window, CONTENTW+2*CONTENTMARGIN, CONTENTH+2*CONTENTMARGIN*CONTENTH/CONTENTW);
|
||||
WMSetWindowAspectRatio(window, CONTENTW,CONTENTH,CONTENTW,CONTENTH);
|
||||
WMSetWindowCloseAction(window, closeAll, NULL);
|
||||
WMSetWindowTitle(window,"GL Frame");
|
||||
WMRealizeWidget(window);
|
||||
datacouple.window=window;
|
||||
WMSetViewNotifySizeChanges(WMWidgetView(window), True);
|
||||
WMAddNotificationObserver(resizeHandler, &datacouple, WMViewSizeDidChangeNotification, WMWidgetView(window));
|
||||
|
||||
|
||||
glframe = WMCreateFrame(window);
|
||||
datacouple.frame=glframe;
|
||||
WMResizeWidget(glframe, CONTENTW, CONTENTH);
|
||||
WMMoveWidget(glframe, CONTENTMARGIN,CONTENTMARGIN);
|
||||
WMRealizeWidget(glframe);
|
||||
|
||||
Button=WMCreateButton(window, WBTMomentaryPush);
|
||||
WMSetButtonAction(Button, DoRotate,&win);
|
||||
WMSetButtonText(Button,"Turn");
|
||||
WMMoveWidget(Button, CONTENTMARGIN,2);
|
||||
WMRealizeWidget(Button);
|
||||
WMMapWidget(Button);
|
||||
|
||||
/* get the frame's X window value */
|
||||
win =W_VIEW_DRAWABLE(WMWidgetView(glframe));
|
||||
WMCreateEventHandler(WMWidgetView(glframe), ExposureMask|StructureNotifyMask,redo,&win);
|
||||
|
||||
xvVisualInfo = glXChooseVisual(display, DefaultScreen(display), Attr);
|
||||
if(xvVisualInfo == NULL) {wwarning("No visualinfo\n");return 0;}
|
||||
|
||||
cmColorMap = XCreateColormap(display,RootWindow(display, DefaultScreen(display)), xvVisualInfo->visual, AllocNone);
|
||||
|
||||
winAttr.colormap = cmColorMap;
|
||||
winAttr.border_pixel = 0;
|
||||
winAttr.background_pixel = 0;
|
||||
winAttr.event_mask = ExposureMask | ButtonPressMask |StructureNotifyMask| KeyPressMask;
|
||||
|
||||
XChangeWindowAttributes(display,win,CWBorderPixel | CWColormap | CWEventMask,&winAttr);
|
||||
glXContext = glXCreateContext(display, xvVisualInfo, None, True);
|
||||
if(!glXContext) {wwarning("glX cannot create rendering context\n");return 0;}
|
||||
|
||||
glXMakeCurrent(display, win, glXContext);
|
||||
|
||||
WMMapWidget(glframe);
|
||||
init();
|
||||
setsize(CONTENTW,CONTENTH);
|
||||
WMMapWidget(window);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
285
WINGs_tutorial/glframe.c.1
Normal file
@@ -0,0 +1,285 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <WINGs/WINGs.h>
|
||||
#include <WINGs/WINGsP.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define CONTENTH 300
|
||||
#define CONTENTW 300
|
||||
#define CONTENTMARGIN 30
|
||||
|
||||
|
||||
struct couple{
|
||||
WMWindow *window;
|
||||
WMFrame *frame;
|
||||
} datacouple;
|
||||
|
||||
|
||||
float red=252.0/256, green=88.0/256, blue=16.0/256;
|
||||
float redb=252.0/256, greenb=242.0/256, blueb=80.0/256;
|
||||
|
||||
int Attr[] = { GLX_RGBA,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 16,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None};
|
||||
Display * display;
|
||||
float alpha=0;
|
||||
|
||||
void init(void)
|
||||
{
|
||||
glClearColor (256/256, 256/256, 256/256, 0.0);
|
||||
glPolygonMode(GL_FRONT, GL_FILL);
|
||||
glPolygonMode(GL_BACK, GL_FILL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
|
||||
GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
GLfloat position[] = { 2.0f, -0.1f, 2.0f, 1.0f };
|
||||
GLfloat position2[] = { -2.0f, -0.26f, -4.0f, 1.0f };
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
|
||||
//glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
|
||||
glMateriali(GL_FRONT, GL_SHININESS, 98);
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, position2);
|
||||
//glLightfv(GL_LIGHT1, GL_POSITION, position2);
|
||||
|
||||
glEnable(GL_LIGHT0);
|
||||
//glEnable(GL_LIGHT1);
|
||||
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
||||
//glColorMaterial(GL_FRONT, GL_SPECULAR);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glCullFace( GL_BACK );
|
||||
glEnable( GL_CULL_FACE );
|
||||
|
||||
glEnable(GL_POLYGON_SMOOTH);
|
||||
/*glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);*/
|
||||
|
||||
}
|
||||
|
||||
void normvector(float a, float aa, float aaa, float b, float bb, float bbb, float c, float cc, float ccc,float *result){
|
||||
float v1[3];float v2[3];float tmp;
|
||||
|
||||
v1[0]=(b-a);v1[1]=(bb-aa);v1[2]=(bbb-aaa);
|
||||
v2[0]=(b-c);v2[1]=(bb-cc);v2[2]=(bbb-ccc);
|
||||
result[0]=(v1[1]*v2[2]-v1[2]*v2[1]);
|
||||
result[1]=(v1[2]*v2[0]-v1[0]*v2[2]);
|
||||
result[2]=(v1[0]*v2[1]-v1[1]*v2[0]);
|
||||
tmp=sqrt(result[0]*result[0]+result[1]*result[1]+result[2]*result[2]);
|
||||
result[0]/=tmp;
|
||||
result[1]/=tmp;
|
||||
result[2]/=tmp;
|
||||
}
|
||||
|
||||
|
||||
void redraw(XEvent * v,void *xw){
|
||||
Window win;
|
||||
float z[3];
|
||||
|
||||
win = *(Window *)xw;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
glPushMatrix(); glShadeModel(GL_SMOOTH);
|
||||
|
||||
glRotatef(alpha, 0, 1, 0);
|
||||
if (alpha > 360) alpha =alpha-360;
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
||||
glColor3f(redb,greenb,blueb);
|
||||
normvector(-0.85f, 0.0f, 0.0f,0.0f, 0.0f, 0.85f,0.0f, 0.6f, 0.0f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(-0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, 0.85f);
|
||||
glVertex3f(0.0f, 0.6f, 0.0f);
|
||||
|
||||
normvector(0.0f, 0.0f,0.85f,0.85f, 0.0f, 0.0f,0.0f, 0.60f,0.0f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.0f, 0.0f, 0.85f);
|
||||
glVertex3f(0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.6f, 0.0f);
|
||||
|
||||
glColor3f(red,green,blue);
|
||||
normvector(0.85f, 0.0f, 0.0f,0.0f, 0.0f, -0.85f,0.0f, 0.6f, 0.0f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, -0.85f);
|
||||
glVertex3f(0.0f, 0.6f, 0.0f);
|
||||
|
||||
normvector(0.0f, 0.0f, -0.85f,-0.85f, 0.0f, 0.0f,0.0f, 0.6f, 0.0f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.0f, 0.0f, -0.85f);
|
||||
glVertex3f(-0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.6f, 0.0f);
|
||||
|
||||
glColor3f(redb,greenb,blueb);
|
||||
normvector(-0.85f, 0.0f, 0.0f,0.0f, -1.0f, 0.0f,0.0f, 0.0f, 0.85f,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(-0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, -1.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, 0.85f);
|
||||
|
||||
normvector(0.0f, 0.0f, 0.85f, 0.0f, -1.0f, 0.0f,0.85f, 0.0f, 0.0f ,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.0f, 0.0f, 0.85f);
|
||||
glVertex3f(0.0f, -1.0f, 0.0f);
|
||||
glVertex3f(0.85f, 0.0f, 0.0f);
|
||||
|
||||
glColor3f(red,green,blue);
|
||||
normvector(0.85f, 0.0f, 0.0f,0.0f, -1.0f, 0.0f, 0.0f, 0.0,-0.85f ,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.85f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f,-1.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, -0.85f);
|
||||
|
||||
normvector(0.0f, 0.0f, -0.85f,0.0f, -1.0f, 0.0f, -0.85f, 0.0f,0.0f ,z);
|
||||
glNormal3fv(z);
|
||||
glVertex3f(0.0f, 0.0f, -0.85f);
|
||||
glVertex3f(0.0f, -1.0f, 0.0f);
|
||||
glVertex3f(-0.85f, 0.0f, 0.0f);
|
||||
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
glXSwapBuffers(display, win);
|
||||
}
|
||||
|
||||
setsize(unsigned int width, unsigned int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
}
|
||||
|
||||
void DoRotate(void *self,void *xwindow){
|
||||
XEvent event;int i=0;
|
||||
alpha+=15;
|
||||
redraw(NULL,(Window *)xwindow);
|
||||
}
|
||||
|
||||
void redo(XEvent * event,void *xw){
|
||||
switch (event->type)
|
||||
{
|
||||
case Expose:
|
||||
if (event->xexpose.count!=0) break;
|
||||
redraw(event,&event->xexpose.window);
|
||||
break;
|
||||
case ConfigureNotify: setsize(event->xconfigure.width, event->xconfigure.height); // assuming there will be an expose afterwards
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void closeAll(WMWidget *self,void *data){
|
||||
WMDestroyWidget(self);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void resizeHandler(void *data, WMNotification *notif){
|
||||
struct couple *tmp;tmp=(struct couple *)data;
|
||||
WMSize size = WMGetViewSize(WMWidgetView(tmp->window));
|
||||
WMResizeWidget(tmp->frame, size.width -2*CONTENTMARGIN, size.height-2*CONTENTMARGIN);
|
||||
}
|
||||
|
||||
void getargs(int argc, char **argv){
|
||||
if (argc>3) {
|
||||
redb=red=(float)atoi(argv[1])/256;
|
||||
greenb=green=(float)atoi(argv[2])/256;
|
||||
blueb=blue=(float)atoi(argv[3])/256;
|
||||
}
|
||||
if (argc>6){
|
||||
redb=(float)atoi(argv[4])/256;
|
||||
greenb=(float)atoi(argv[5])/256;
|
||||
blueb=(float)atoi(argv[6])/256;
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char **argv){
|
||||
|
||||
WMFrame *glframe;
|
||||
WMScreen *screen;
|
||||
WMWindow *window;
|
||||
WMButton *Button;
|
||||
|
||||
|
||||
/* Xlib and glX variables */
|
||||
Window win;
|
||||
XVisualInfo *xvVisualInfo;
|
||||
Colormap cmColorMap;
|
||||
XSetWindowAttributes winAttr;
|
||||
GLXContext glXContext;
|
||||
|
||||
getargs(argc,argv);
|
||||
WMInitializeApplication("GLWindow", &argc, argv);
|
||||
display = XOpenDisplay("");
|
||||
screen = WMCreateScreen(display, DefaultScreen(display));
|
||||
|
||||
if(!glXQueryExtension(display, NULL, NULL)){wwarning("X server does not have GLX\n"); return 0; }
|
||||
|
||||
window = WMCreateWindow(screen, "Main");
|
||||
WMResizeWidget(window, CONTENTW+2*CONTENTMARGIN, CONTENTH+2*CONTENTMARGIN*CONTENTH/CONTENTW);
|
||||
WMSetWindowAspectRatio(window, CONTENTW,CONTENTH,CONTENTW,CONTENTH);
|
||||
WMSetWindowCloseAction(window, closeAll, NULL);
|
||||
WMSetWindowTitle(window,"GL Frame");
|
||||
WMRealizeWidget(window);
|
||||
datacouple.window=window;
|
||||
WMSetViewNotifySizeChanges(WMWidgetView(window), True);
|
||||
WMAddNotificationObserver(resizeHandler, &datacouple, WMViewSizeDidChangeNotification, WMWidgetView(window));
|
||||
|
||||
|
||||
glframe = WMCreateFrame(window);
|
||||
datacouple.frame=glframe;
|
||||
WMResizeWidget(glframe, CONTENTW, CONTENTH);
|
||||
WMMoveWidget(glframe, CONTENTMARGIN,CONTENTMARGIN);
|
||||
WMRealizeWidget(glframe);
|
||||
|
||||
Button=WMCreateButton(window, WBTMomentaryPush);
|
||||
WMSetButtonAction(Button, DoRotate,&win);
|
||||
WMSetButtonText(Button,"Turn");
|
||||
WMMoveWidget(Button, CONTENTMARGIN,2);
|
||||
WMRealizeWidget(Button);
|
||||
WMMapWidget(Button);
|
||||
|
||||
/* get the frame's X window value */
|
||||
win =W_VIEW_DRAWABLE(WMWidgetView(glframe));
|
||||
WMCreateEventHandler(WMWidgetView(glframe), ExposureMask|StructureNotifyMask,redo,&win);
|
||||
|
||||
xvVisualInfo = glXChooseVisual(display, DefaultScreen(display), Attr);
|
||||
if(xvVisualInfo == NULL) {wwarning("No visualinfo\n");return 0;}
|
||||
|
||||
cmColorMap = XCreateColormap(display,RootWindow(display, DefaultScreen(display)), xvVisualInfo->visual, AllocNone);
|
||||
|
||||
winAttr.colormap = cmColorMap;
|
||||
winAttr.border_pixel = 0;
|
||||
winAttr.background_pixel = 0;
|
||||
winAttr.event_mask = ExposureMask | ButtonPressMask |StructureNotifyMask| KeyPressMask;
|
||||
|
||||
XChangeWindowAttributes(display,win,CWBorderPixel | CWColormap | CWEventMask,&winAttr);
|
||||
glXContext = glXCreateContext(display, xvVisualInfo, None, True);
|
||||
if(!glXContext) {wwarning("glX cannot create rendering context\n");return 0;}
|
||||
|
||||
glXMakeCurrent(display, win, glXContext);
|
||||
|
||||
WMMapWidget(glframe);
|
||||
init();
|
||||
setsize(CONTENTW,CONTENTH);
|
||||
WMMapWidget(window);
|
||||
|
||||
WMScreenMainLoop(screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||