Add WINGs tutorial
[whome.git] / WINGs_tutorial / WINGGraphics.html
blob7edd5f181d5e58c41b5aa73f0054532f28f31222
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <!-- saved from url=(0077)WINGGraphics.html -->
3 <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>
4 <meta http-equiv="Content-Type" content="text/html">
5 <meta name="keywords" content="WINGs, tutorial,X11, Xlib,graphics, GUI, Window Maker, OpenGL, Mesa">
6 <meta name="description" content="WINGs library tutorial">
7 <meta name="license" content="GNU Free Documentation License">
9 </head>
11 <body>
12 <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>
14 <h4>Drawing procedures</h4>
16 <h5>The drawable</h5>
17 <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 &lt;WINGs/WINGsP.h&gt;</code>.
18 </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:
19 </p><pre><code>
20 void drawProcedure(XEvent *event, void *data){
21 WMDrawPixmap(pixmap, W_VIEW_DRAWABLE(WMWidgetView(data)),30,30);XFlush(display);
23 int main (){
24 /* code */
25 WMCreateEventHandler(WMWidgetView(win), ExposureMask,drawProcedure,win);
26 /* */ }</code></pre>
27 <p>
28 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.
30 </p><h5>Xlib graphics functions</h5>
31 <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-&gt;gray)</code> from that point on. The next lines are drawn with default line width. The example is <a href="SeventhWindow.c">here</a>.
33 </p><p>Useful Xlib functions and structures are
34 </p><ul>
35 <li><code> int XDrawRectangle(Display *display, Drawable d, GC gc,
36 int x, int y, unsigned int width, unsigned int
37 height)</code></li><li><code>
38 int XDrawLines(Display *display, Drawable d, GC gc, XPoint
39 *points, int npoints, int mode)</code></li><li><code>
41 int XDrawSegments(Display *display, Drawable d, GC gc,
42 XSegment *segments, int nsegments)</code></li><li><code>
44 int XDrawArc(Display *display, Drawable d, GC gc, int x,
45 int y, unsigned int width, unsigned int height, int
46 angle1, int angle2)</code></li><li><code>
47 int XDrawArcs(Display *display, Drawable d, GC gc, XArc
48 *arcs, int narcs)</code></li><li><code>
49 int XDrawPoint(Display *display, Drawable d, GC gc, int x,
50 int y)</code></li><li><code>
52 int XDrawPoints(Display *display, Drawable d, GC gc,
53 XPoint *points, int npoints, int mode)</code></li><li><code>
55 GC XCreateGC(Display *display, Drawable d, unsigned long
56 valuemask, XGCValues *values)</code></li><li><code>
57 int XFillArc(Display *display, Drawable d, GC gc, int x,
58 int y, unsigned int width, unsigned int height, int
59 angle1, int angle2)</code></li><li><code>
60 int XFillPolygon(Display *display, Drawable d, GC gc,
61 XPoint *points, int npoints, int shape, int mode)</code></li><li><code>
64 typedef struct {
65 short x1, y1, x2, y2;
66 } XSegment</code></li><li><code>
68 typedef struct {
69 short x, y;
70 } XPoint</code></li><li><code>
73 typedef struct {
74 short x, y;
75 unsigned short width, height;
76 short angle1, angle2; /* Degrees * 64 */
77 } XArc</code>
78 </li></ul>
79 <p>The XFree XLib man pages are <a href="http://www.xfree86.org/current/manindex3.html">here</a> in 2010.
82 </p><h5><a name="talkOpenGL">An OpenGL drawing area</a></h5>
83 <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.
84 </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
85 </p><pre><code>win =W_VIEW_DRAWABLE(WMWidgetView(glframe));</code></pre>
86 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.
87 <pre><code>Window win;
88 XVisualInfo *xvVisualInfo;
89 Colormap usColorMap;
90 XSetWindowAttributes winAttr;
91 GLXContext glXContext;
92 int Attributes[] = { GLX_RGBA,
93 GLX_RED_SIZE, 8,
94 GLX_GREEN_SIZE, 8,
95 GLX_BLUE_SIZE, 8,
96 GLX_DEPTH_SIZE, 16,
97 GLX_DOUBLEBUFFER,
98 None};
99 xvVisualInfo = glXChooseVisual(display, DefaultScreen(display), Attributes);
100 cmColorMap = XCreateColormap(display,RootWindow(display, DefaultScreen(display)), usVisualInfo-&gt;visual, AllocNone);
101 winAttr.colormap = usColorMap;
102 winAttr.border_pixel = 0;
103 winAttr.background_pixel = 0;
104 winAttr.event_mask = ExposureMask | ButtonPressMask |StructureNotifyMask| KeyPressMask;
106 XChangeWindowAttributes(display,win,CWBorderPixel | CWColormap | CWEventMask,&amp;winAttr);
107 glXContext = glXCreateContext(display, xvVisualInfo, None, True);
108 glXMakeCurrent(display, win, glXContext);</code></pre>
109 <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>.
110 </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.
114 <br>
115 </p><p>
116 </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>
119 </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>