File: sec-gdkvisual.html

package info (click to toggle)
ebook-dev-ggad 199908-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 2,264 kB
  • ctags: 1,163
  • sloc: sh: 44; makefile: 35
file content (583 lines) | stat: -rw-r--r-- 23,800 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>
      Visuals and Colormaps
    </title>
    <meta name="GENERATOR" content=
    "Modular DocBook HTML Stylesheet Version 1.45">
    <link rel="HOME" title="GTK+ / Gnome Application Development"
    href="ggad.html">
    <link rel="UP" title="GDK Basics" href="cha-gdk.html">
    <link rel="PREVIOUS" title="GdkWindow" href=
    "sec-gdkwindow.html">
    <link rel="NEXT" title="Drawables and Pixmaps" href= 
    "sec-gdkdrawable.html">
  </head>
  <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink= 
  "#840084" alink="#0000FF">
    <div class="NAVHEADER">
      <table width="100%" border="0" bgcolor="#ffffff" cellpadding= 
      "1" cellspacing="0">
        <tr>
          <th colspan="4" align="center">
            <font color="#000000" size="2">GTK+ / Gnome Application
            Development</font>
          </th>
        </tr>
        <tr>
          <td width="25%" bgcolor="#ffffff" align="left">
            <a href="sec-gdkwindow.html"><font color="#0000ff"
            size="2"><b>&lt;&lt;&lt; Previous</b></font></a>
          </td>
          <td width="25%" colspan="2" bgcolor="#ffffff" align= 
          "center">
            <font color="#0000ff" size="2"><b><a href="ggad.html">
            <font color="#0000ff" size="2"><b>
            Home</b></font></a></b></font>
          </td>
          <td width="25%" bgcolor="#ffffff" align="right">
            <a href="sec-gdkdrawable.html"><font color="#0000ff"
            size="2"><b>Next &gt;&gt;&gt;</b></font></a>
          </td>
        </tr>
      </table>
    </div>
    <div class="SECT1">
      <h1 class="SECT1">
        <a name="SEC-GDKVISUAL">Visuals and Colormaps</a>
      </h1>
      <p>
        Unfortunately, not all hardware is created equal. The most
        primitive X servers support only two colors; each pixel is
        either on or off. This is referred to as a "one bit per
        pixel (bpp)" display. A display with one bit per pixel is
        said to have a <i class="FIRSTTERM">depth</i> of one. More
        advanced X servers support 24 or 32 bits per pixel, and
        allow you to specify a different depth on a
        window-by-window basis. 24 bits per pixel allows 2^24
        different pixels, which includes more colors than the human
        eye can differentiate.
      </p>
      <p>
        Conceptually, a bitmap display consists of a rectangular
        grid of pixels. Each pixel consists of some fixed number of
        bits; pixels are mapped to visible colors in a
        hardware-dependent way. One way to think about this is to
        imagine a two-dimensional array of integers, where the
        integer size is chosen to hold the required number of bits.
        Alternatively, you can think of a display like this as a
        stack of <i class="FIRSTTERM">bit planes</i>, or
        two-dimensional arrays of bits. If all the planes are
        parallel to one another, a pixel is a perpendicular line
        passing through the same coordinates on each plane, taking
        a single bit from each one. This is the origin of the term
        <i class="FIRSTTERM">depth</i>, since the number of bits
        per pixel is equal to the depth of the stack of bit planes.
      </p>
      <p>
        In the X Window System, pixels represent entries in a color
        lookup table. A <i class="FIRSTTERM">color</i> is a red,
        green, blue (RGB) value---monitors mix red, green, and blue
        light in some ratio to display each pixel. Take an eight
        bit display, for example: eight bits are not enough to
        encode a color in-place; only a few arbitrary RGB values
        would be possible. Instead, the bits are interpreted as an
        integer and used to index an array of RGB color values.
        This table of colors is called the <i class="FIRSTTERM">
        colormap</i>; it can sometimes be modified to contain the
        colors you plan to use, though this is
        hardware-dependent---some colormaps are read-only.
      </p>
      <p>
        A <i class="FIRSTTERM">visual</i> is required to determine
        how a pixel's bit pattern is converted into a visible
        color. Thus, a visual also defines how colormaps work. On
        an 8-bit display, the X server might interpret each pixel
        as an index into a single colormap containing the 256
        possible colors. 24-bit visuals typically have three
        colormaps: one for shades of red, one for shades of green,
        and one for shades of blue. Each colormap is indexed with
        an eight-bit value; the three eight-bit values are packed
        into a 24-bit pixel. The visual defines the meaning of the
        pixel contents. Visuals also define whether the colormap is
        read-only or modifiable.
      </p>
      <p>
        In short, a visual is a description of the color
        capabilities of a particular X server. In Xlib, you have to
        do a lot of fooling around with visuals; GDK and GTK+
        shield you from most of the mess.
      </p>
      <div class="SECT2">
        <h2 class="SECT2">
          <a name="Z114"><span class="STRUCTNAME">
          GdkVisual</span></a>
        </h2>
        <p>
          Xlib can report a list of all available visuals and
          information about each; GDK keeps a client-side copy of
          this information in a struct called <span class= 
          "STRUCTNAME">GdkVisual</span>. GDK can report the
          available visuals, and rank them in different ways. Most
          of the time you will only use <tt class="FUNCTION">
          gdk_visual_get_system()</tt>, which returns a pointer to
          the default visual (<a href= 
          "sec-gdkvisual.html#FL-GDKVISUAL">Figure 2</a>). (If
          you're writing a <tt class="CLASSNAME">GtkWidget</tt>,
          <tt class="FUNCTION">gtk_widget_get_visual()</tt> returns
          the visual you should use; more on this in <a href= 
          "cha-widget.html">the chapter called <i>Writing a <tt
          class="CLASSNAME">GtkWidget</tt></i></a>.) The returned
          visual is not a copy, so there is no need to free it; GDK
          keeps visuals around permanently.
        </p>
        <div class="FIGURE">
          <a name="FL-GDKVISUAL"></a>
          <div class="FUNCSYNOPSIS">
            <a name="FL-GDKVISUAL.SYNOPSIS"></a>
            <table border="0" bgcolor="#E0E0E0" width="100%">
              <tr>
                <td>
<pre class="FUNCSYNOPSISINFO">
#include &lt;gdk/gdk.h&gt;
</pre>
                </td>
              </tr>
            </table>
            <p>
              <code><code class="FUNCDEF">GdkVisual* <tt class= 
              "FUNCTION">
              gdk_visual_get_system</tt></code>(void);</code>
            </p>
          </div>
          <p>
            <b>Figure 2. Default Visual</b>
          </p>
        </div>
        <p>
          For reference, here are the contents of <span class= 
          "STRUCTNAME">GdkVisual</span>; most of the members are
          used to calculate pixel values from colors. Since this is
          fairly involved and rarely used, this book glosses over
          the topic. The <span class="STRUCTNAME">depth</span>
          member is convenient sometimes. <a href= 
          "sec-gdkvisual.html#SEC-TYPESOFVISUAL">the section called
          <i>Types of Visual</i></a> has more to say about the
          <span class="STRUCTNAME">type</span> member.
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;typedef struct _GdkVisual GdkVisual;

struct _GdkVisual
{
  GdkVisualType type;
  gint depth;
  GdkByteOrder byte_order;
  gint colormap_size;
  gint bits_per_rgb;

  guint32 red_mask;
  gint red_shift;
  gint red_prec;

  guint32 green_mask;
  gint green_shift;
  gint green_prec;

  guint32 blue_mask;
  gint blue_shift;
  gint blue_prec;
};&#13;
</pre>
            </td>
          </tr>
        </table>
        <div class="SECT3">
          <h3 class="SECT3">
            <a name="SEC-TYPESOFVISUAL">Types of Visual</a>
          </h3>
          <p>
            Visuals differ along several dimensions. They can be
            grayscale or RGB, colormaps can be modifiable or fixed,
            and the pixel value can either index a single colormap
            or contain packed red, green, and blue indexes. Here
            are the possible values for <span class="STRUCTNAME">
            GdkVisualType</span>:
          </p>
          <ul>
            <li>
              <p>
                <span class="STRUCTNAME">
                GDK_VISUAL_STATIC_GRAY</span> means the display is
                either monochrome or gray scale, and the colormap
                cannot be modified. A pixel value is simply a level
                of gray; each pixel is "hard coded" to represent a
                certain on-screen color.&#13;
              </p>
            </li>
            <li>
              <p>
                <span class="STRUCTNAME">
                GDK_VISUAL_GRAYSCALE</span> means the display has a
                modifiable colormap, but only levels of gray are
                possible. The pixel represents an entry in the
                colormap, so a given pixel can represent a
                different level of gray at different times.&#13;
              </p>
            </li>
            <li>
              <p>
                <span class="STRUCTNAME">
                GDK_VISUAL_STATIC_COLOR</span> represents a color
                display which uses a single read-only colormap
                rather than a separate colormap for each of red,
                green, and blue. The display is almost certainly
                12-bit or less (a 24-bit display using a single
                colormap would need a colormap with 2^24 entries,
                occupying close to half a gigabyte---not very
                practical!). This is an annoying visual, because
                relatively few colors are available and you can't
                change which colors they are.&#13;
              </p>
            </li>
            <li>
              <p>
                <span class="STRUCTNAME">
                GDK_VISUAL_PSEUDO_COLOR</span> is the most common
                visual on low-end PC hardware from several years
                ago. If you have a one-megabyte 256-color video
                card, this is most likely your X server's visual.
                It represents a color display with a read/write
                colormap. Pixels index a single colormap.&#13;
              </p>
            </li>
            <li>
              <p>
                <span class="STRUCTNAME">
                GDK_VISUAL_TRUE_COLOR</span> is a color display
                with three read-only colormaps, one for each of
                red, green, and blue. A pixel contains three
                indexes, one per colormap. There is a fixed
                mathematical relationship between pixels and RGB
                triplets; you can get a pixel from red, green, and
                blue values in [0, 255] using the formula: <span
                class="STRUCTNAME">gulong pixel =
                (gulong)(red*65536 + green*256 + blue)</span>.
                &#13;
              </p>
            </li>
            <li>
              <p>
                <span class="STRUCTNAME">
                GDK_VISUAL_DIRECT_COLOR</span> is a color display
                with three read-write colormaps. If you use the GDK
                color handling routines, they simply fill up all
                three colormaps to emulate a true color display,
                then pretend the direct color display is true
                color.&#13;
              </p>
            </li>
          </ul>
        </div>
      </div>
      <div class="SECT2">
        <h2 class="SECT2">
          <a name="Z115">Color and <span class="STRUCTNAME">
          GdkColormap</span></a>
        </h2>
        <p>
          A <span class="STRUCTNAME">GdkColor</span> stores an RGB
          value and a pixel. Red, green, and blue are given as
          16-bit unsigned integers; so they are in the range [0,
          65535]. The contents of the pixel depend on the visual.
          Here is <span class="STRUCTNAME">GdkColor</span>:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;typedef struct _GdkColor GdkColor;

struct _GdkColor
{
  gulong  pixel;
  gushort red;
  gushort green;
  gushort blue;
};&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          Before you can use a color to draw, you must:
        </p>
        <ul>
          <li>
            <p>
              Ensure that the pixel value contains an appropriate
              value.&#13;
            </p>
          </li>
          <li>
            <p>
              Ensure that the color exists in the colormap of the
              drawable you intend to draw to. (A <i class=
              "FIRSTTERM">drawable</i> is a window or pixmap you
              can draw to; see <a href="sec-gdkdrawable.html">the
              section called <i>Drawables and
              Pixmaps</i></a>.)&#13;
            </p>
          </li>
        </ul>
        <p>
          In Xlib, this is an enormously complicated process,
          because it has to be done differently for every kind of
          visual. GDK conceals things fairly well. You simply call
          <tt class="FUNCTION">gdk_colormap_alloc_color()</tt> to
          fill in the pixel value and add the color to the colormap
          (<a href="sec-gdkvisual.html#FL-COLORALLOC">Figure
          3</a>). Here is an example; it assumes a preexisting
          <span class="STRUCTNAME">GdkColormap* colormap</span>,
          which should be the colormap of the drawable you are
          targetting:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;  GdkColor color;
  
  /* Describe a pure red */
  color.red   = 65535;
  color.green = 0;
  color.blue  = 0;

  if (gdk_colormap_alloc_color(colormap, &amp;color, FALSE, TRUE))
    {
      /* Success! */
    }&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          If <tt class="FUNCTION">gdk_colormap_alloc_color()</tt>
          returns <span class="STRUCTNAME">TRUE</span>, then the
          color was allocated and <span class="STRUCTNAME">
          color.pixel</span> contains a valid value. The color can
          then be used to draw. The two boolean arguments to <tt
          class="FUNCTION">gdk_colormap_alloc_color()</tt> specify
          whether the color should be <i class="FIRSTTERM">
          writeable</i>, and whether to try to find a "best match"
          if the color can't be allocated. If a best match is used
          instead of allocating a new color, the color's RGB values
          will be changed to the best match. If you request a best
          match for a non-writeable entry, allocation really should
          not fail, since even on a black and white display either
          black or white will be the best match; only an empty
          colormap could cause failure. The only way to get an
          empty colormap is to create a custom colormap yourself.
          If you don't ask for the best match, failure is quite
          possible on displays with a limited number of colors.
          Failure is always possible with writeable colormap
          entries (where best match makes no sense, because the
          entry can be modified).
        </p>
        <p>
          A <i class="FIRSTTERM">writeable</i> colormap entry is
          one that you can change at any time; some visuals support
          this, and some don't. The purpose of a writeable colormap
          entry is to change an on-screen color without redrawing
          the graphics. Some hardware stores pixels as indices into
          a color lookup table, so changing the lookup table
          changes how the pixels are displayed. The disadvantages
          of writeable colormap entries are numerous. Most notably:
          not all visuals support them, and writeable colormap
          entries can't be used by other applications (read-only
          entries can be shared, since other applications know the
          color will remain constant). Thus, it is a good idea to
          avoid allocating writeable colors. On modern hardware,
          they are more trouble than they're worth; the speed gain
          compared to simply redrawing your graphics will not be
          noticeable.
        </p>
        <p>
          When you're finished with a color, you can remove it from
          the colormap with <tt class="FUNCTION">
          gdk_colormap_free_colors()</tt>. This is only really
          important for pseudo color and grayscale visuals, where
          colors are in short supply and the colormap can be
          modified by clients. GDK will automatically do the right
          thing for each visual type, so always call this function.
        </p>
        <p>
          A convenient way to obtain RGB values is the <tt class= 
          "FUNCTION">gdk_color_parse()</tt> function. This takes an
          X color specification, and fills in the <span class= 
          "STRUCTNAME">red</span>, <span class="STRUCTNAME">
          green</span>, and <span class="STRUCTNAME">blue</span>
          fields of a <span class="STRUCTNAME">GdkColor</span>. An
          X color specification can have many forms; one
          possibility is an RGB string:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13; RGB:FF/FF/FF&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          This specifies white (red, green, and blue are all at
          full intensity). The <span class="STRUCTNAME">RGB:</span>
          specifies a "color space," and determines the meaning of
          the numbers after it. X also understands several more
          obscure color spaces. If the color specification string
          doesn't begin with a recognized color space, X assumes
          it's a color name and looks it up in a database of names.
          So you can write code like this:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;  GdkColor color;

  if (gdk_color_parse("orange", &amp;color))
    {
      if (gdk_colormap_alloc_color(colormap, &amp;color, FALSE, TRUE))
        {
          /* We have orange! */
        }
    } &#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          As you can see, <tt class="FUNCTION">
          gdk_color_parse()</tt> returns <span class="STRUCTNAME">
          TRUE</span> if it figures out the string you pass it.
          There is no way to know exactly what will be in the color
          database, so always check this return value.
        </p>
        <div class="FIGURE">
          <a name="FL-COLORALLOC"></a>
          <div class="FUNCSYNOPSIS">
            <a name="FL-COLORALLOC.SYNOPSIS"></a>
            <table border="0" bgcolor="#E0E0E0" width="100%">
              <tr>
                <td>
<pre class="FUNCSYNOPSISINFO">
#include &lt;gdk/gdk.h&gt;
</pre>
                </td>
              </tr>
            </table>
            <p>
              <code><code class="FUNCDEF">gboolean <tt class= 
              "FUNCTION">
              gdk_colormap_alloc_color</tt></code>(GdkColormap* <tt
              class="PARAMETER"><i>colormap</i></tt>, GdkColor* <tt
              class="PARAMETER"><i>color</i></tt>, gboolean <tt
              class="PARAMETER"><i>writeable</i></tt>, gboolean <tt
              class="PARAMETER"><i>best_match</i></tt>);</code>
            </p>
            <p>
              <code><code class="FUNCDEF">void <tt class=
              "FUNCTION">
              gdk_colormap_free_colors</tt></code>(GdkColormap* <tt
              class="PARAMETER"><i>colormap</i></tt>, GdkColor* <tt
              class="PARAMETER"><i>colors</i></tt>, gint <tt class= 
              "PARAMETER"><i>ncolors</i></tt>);</code>
            </p>
            <p>
              <code><code class="FUNCDEF">gint <tt class=
              "FUNCTION">gdk_color_parse</tt></code>(gchar* <tt
              class="PARAMETER"><i>spec</i></tt>, GdkColor* <tt
              class="PARAMETER"><i>color</i></tt>);</code>
            </p>
          </div>
          <p>
            <b>Figure 3. Color Allocation</b>
          </p>
        </div>
        <div class="SECT3">
          <h3 class="SECT3">
            <a name="Z116">Obtaining a Colormap</a>
          </h3>
          <p>
            If you're writing a <tt class="CLASSNAME">
            GtkWidget</tt> subclass, the correct way to obtain a
            colormap is with <tt class="FUNCTION">
            gtk_widget_get_colormap()</tt> (see <a href= 
            "cha-widget.html">the chapter called <i>Writing a <tt
            class="CLASSNAME">GtkWidget</tt></i></a>). Otherwise,
            the system (default) colormap is usually what you want;
            call <tt class="FUNCTION">
            gdk_colormap_get_system()</tt>, which takes no
            arguments and returns the default colormap.
          </p>
          <p>
            The GdkRGB module (see <a href="z132.html#SEC-GDKRGB">
            the section called <i>RGB Buffers</i></a>) is another
            way to deal with colors; among other capabilities, it
            can set the foreground and background colors of a
            graphics context from an RGB value. The relevant
            functions are <tt class="FUNCTION">
            gdk_rgb_gc_set_foreground()</tt> and <tt class=
            "FUNCTION">gdk_rgb_gc_set_background()</tt>. GdkRGB has
            a pre-allocated colormap that it uses to pick a
            best-match color; using it means that your application
            can share limited colormap resources with other
            applications using GdkRGB (such as the Gimp). You can
            also obtain GdkRGB's colormap and use it directly (see
            <a href="z132.html#SEC-GDKRGB">the section called <i>
            RGB Buffers</i></a>).
          </p>
        </div>
      </div>
    </div>
    <div class="NAVFOOTER">
      <br>
      <br>
      <table width="100%" border="0" bgcolor="#ffffff" cellpadding= 
      "1" cellspacing="0">
        <tr>
          <td width="25%" bgcolor="#ffffff" align="left">
            <a href="sec-gdkwindow.html"><font color="#0000ff"
            size="2"><b>&lt;&lt;&lt; Previous</b></font></a>
          </td>
          <td width="25%" colspan="2" bgcolor="#ffffff" align= 
          "center">
            <font color="#0000ff" size="2"><b><a href="ggad.html">
            <font color="#0000ff" size="2"><b>
            Home</b></font></a></b></font>
          </td>
          <td width="25%" bgcolor="#ffffff" align="right">
            <a href="sec-gdkdrawable.html"><font color="#0000ff"
            size="2"><b>Next &gt;&gt;&gt;</b></font></a>
          </td>
        </tr>
        <tr>
          <td colspan="2" align="left">
            <font color="#000000" size="2"><b><span class= 
            "STRUCTNAME">GdkWindow</span></b></font>
          </td>
          <td colspan="2" align="right">
            <font color="#000000" size="2"><b>Drawables and
            Pixmaps</b></font>
          </td>
        </tr>
      </table>
    </div>
  </body>
</html>