~ubuntu-branches/ubuntu/quantal/openmotif/quantal

« back to all changes in this revision

Viewing changes to clients/mwm/WmColormap.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bauer
  • Date: 2010-06-23 12:12:31 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100623121231-u89gxdp51sg9wjj2
Tags: 2.3.0-1
* New Maintainer (Closes: #379258) 
* Acknowledge NMU changes
* New upstream release (Closes: #494375)
* Get rid of security patches as they are already part of new upstream
  release (00-xpmvuln.openmotif.patch, 342092-CVE-2005-3964.patch)
* Bump Standards to 3.8.4
* Added {misc:Depends} to make the package lintian cleaner
* Fix weak-library-dev-dependency by adding ${binary:Version}) for the
  -dev Package of openmotif
* Let package depend on autotools-dev to use newer autotools-helper-files
* Work around an autoconf-bug (Gentoo-Bug #1475)
* Added Client-side anti-aliased fonts support via XFT
* Added UTF-8 and UTF8_STRING atom support
* Ability to show text and pixmaps in Label, LabelGadget and all
  derived widgets
* Support of PNG/JPEG image formats in the same way as XPM is supported
* Increase FILE_OFFSET_BITS to 64 to show files >2GB in file-selector
  Idea taken from Magne Oestlyngen (Closes: #288537)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * @OPENGROUP_COPYRIGHT@
 
3
 * COPYRIGHT NOTICE
 
4
 * Copyright (c) 1989, 1990, 1991, 1992, 1993 Open Software Foundation, Inc. 
 
5
 * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
 
6
 * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
 
7
 * the full copyright text.
 
8
 * 
 
9
 * This software is subject to an open license. It may only be
 
10
 * used on, with or for operating systems which are themselves open
 
11
 * source systems. You must contact The Open Group for a license
 
12
 * allowing distribution and sublicensing of this software on, with,
 
13
 * or for operating systems which are not Open Source programs.
 
14
 * 
 
15
 * See http://www.opengroup.org/openmotif/license for full
 
16
 * details of the license agreement. Any use, reproduction, or
 
17
 * distribution of the program constitutes recipient's acceptance of
 
18
 * this agreement.
 
19
 * 
 
20
 * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
 
21
 * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
22
 * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 
23
 * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
 
24
 * OR FITNESS FOR A PARTICULAR PURPOSE
 
25
 * 
 
26
 * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
 
27
 * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
 
28
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
29
 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
 
30
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
31
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 
32
 * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
 
33
 * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
 
34
 * POSSIBILITY OF SUCH DAMAGES.
 
35
*/ 
 
36
/* 
 
37
 * Motif Release 1.2.3
 
38
*/ 
 
39
#ifdef HAVE_CONFIG_H
 
40
#include <config.h>
 
41
#endif
 
42
 
 
43
 
 
44
#ifdef REV_INFO
 
45
#ifndef lint
 
46
static char rcsid[] = "$XConsortium: WmColormap.c /main/5 1996/10/30 11:14:44 drk $"
 
47
#endif
 
48
#endif
 
49
/*
 
50
 * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
 
51
 
 
52
/*
 
53
 * Included Files:
 
54
 */
 
55
 
 
56
#include "WmGlobal.h"
 
57
 
 
58
/*
 
59
 * include extern functions
 
60
 */
 
61
 
 
62
#include "WmColormap.h"
 
63
#include "WmKeyFocus.h"
 
64
 
 
65
static Bool ProcessEvents(Display *dpy, XEvent *Event, char *c_pCD);
 
66
 
 
67
 
 
68
/* Global variables */
 
69
        static unsigned long firstRequest, lastRequest;
 
70
 
 
71
 
 
72
/*************************************<->*************************************
 
73
 *
 
74
 *  InitWorkspaceColormap ()
 
75
 *
 
76
 *
 
77
 *  Description:
 
78
 *  -----------
 
79
 *  This function sets up the default workspace colormap and prepares for
 
80
 *  workspace colormap processing.
 
81
 *
 
82
 *
 
83
 *  Inputs:
 
84
 *  -------
 
85
 *  pSD = ptr to screen data
 
86
 * 
 
87
 *  Outputs:
 
88
 *  -------
 
89
 *  wmGD = (workspaceColormap)
 
90
 * 
 
91
 *************************************<->***********************************/
 
92
 
 
93
void InitWorkspaceColormap (WmScreenData *pSD)
 
94
{
 
95
    /*
 
96
     * Setup the default (workspace) colormap:
 
97
     * !!! this should be made more general to get the colormap for the !!!
 
98
     * !!! workspace (root) and then track colormap changes             !!!
 
99
     */
 
100
 
 
101
    pSD->workspaceColormap = DefaultColormap (DISPLAY, pSD->screen);
 
102
 
 
103
} /* END OF FUNCTION InitWorkspaceColormap */
 
104
 
 
105
 
 
106
 
 
107
/*************************************<->*************************************
 
108
 *
 
109
 *  InitColormapFocus (pSD)
 
110
 *
 
111
 *
 
112
 *  Description:
 
113
 *  -----------
 
114
 *  This function prepares for managing the colormap focus and sets the
 
115
 *  initial colormap focus (if the focus policy is "keyboard" - i.e. the
 
116
 *  colormap focus tracks the keyboard focus) the initial colormap
 
117
 *  installation is done in InitKeyboardFocus.
 
118
 *
 
119
 *  Inputs:
 
120
 *  -------
 
121
 *  pSD = pointer to screen data
 
122
 *
 
123
 *  Outputs:
 
124
 *  -------
 
125
 *  *pSD = (colormapFocus)
 
126
 * 
 
127
 *************************************<->***********************************/
 
128
 
 
129
void InitColormapFocus (WmScreenData *pSD)
 
130
{
 
131
    ClientData *pCD;
 
132
    Boolean sameScreen;
 
133
 
 
134
 
 
135
    /*
 
136
     * Set up the initial colormap focus.  If the colormapFocusPolicy is
 
137
     * "keyboard" or it is "pointer" and the keyboard input focus policy
 
138
     * is "pointer" then set up the initial colormap focus when the
 
139
     * initial keyboard input focus is set up.
 
140
     */
 
141
 
 
142
    pSD->colormapFocus = NULL;
 
143
 
 
144
    if (wmGD.colormapFocusPolicy == CMAP_FOCUS_POINTER)
 
145
    {
 
146
        if (wmGD.keyboardFocusPolicy != KEYBOARD_FOCUS_POINTER)
 
147
        {
 
148
            if ((pCD = GetClientUnderPointer (&sameScreen)) != NULL)
 
149
            {
 
150
                SetColormapFocus (pSD, pCD);
 
151
            }
 
152
            else
 
153
            {
 
154
                WmInstallColormap (pSD, pSD->workspaceColormap);
 
155
            }
 
156
        }
 
157
    }
 
158
    else
 
159
    {
 
160
        WmInstallColormap (pSD, pSD->workspaceColormap);
 
161
    }
 
162
 
 
163
} /* END OF FUNCTION InitColormapFocus */
 
164
 
 
165
 
 
166
 
 
167
#ifndef OLD_COLORMAP
 
168
/*************************************<->*************************************
 
169
 *
 
170
 *  ForceColormapFocus (pSD, pCD)
 
171
 *
 
172
 *
 
173
 *  Description:
 
174
 *  -----------
 
175
 * ForceColormapFocus is the working part of the original SetColormapFocus.
 
176
 * This function is used to unconditionally set the colormap focus to a
 
177
 * particular client window or to clear the colormap focus (set focus to
 
178
 * the root window).
 
179
 *
 
180
 * The reason is to permit focus to be dtrced.  We need to do this because
 
181
 * we can already have colormap focus, but still need to set the colormaps.
 
182
 * Examples of when this occurs are:
 
183
 *
 
184
 *      * after the window manager itself has forced a colormap,
 
185
 *        as happens when it draws transients in the overlay planes.
 
186
 *      * when WM_COLORMAP_WINDOWS changes.
 
187
 *      * when a ColormapNotify (new) event is received.
 
188
 *
 
189
 *
 
190
 *  Inputs:
 
191
 *  ------
 
192
 *  pSD = pointer to Screen Data
 
193
 *  pCD = pointer to client data (clientColormap ...)
 
194
 *
 
195
 *************************************<->***********************************/
 
196
 
 
197
void ForceColormapFocus (WmScreenData *pSD, ClientData *pCD)
 
198
{
 
199
    if (pCD && ((pCD->clientState == NORMAL_STATE) ||
 
200
                (pCD->clientState == MAXIMIZED_STATE)))
 
201
    {
 
202
        pSD->colormapFocus = pCD;
 
203
#ifndef OLD_COLORMAP /* colormaps */
 
204
        ProcessColormapList (pSD, pCD);
 
205
#else /* OSF original */
 
206
        WmInstallColormap (pSD, pCD->clientColormap);
 
207
#endif
 
208
    }
 
209
    else
 
210
    {
 
211
        /*
 
212
         * The default colormap is installed for minimized windows that have
 
213
         * the colormap focus.
 
214
         * !!! should colormaps be installed for icons with client      !!!
 
215
         * !!! icon windows?  should the client colormap be installed ? !!!
 
216
         */
 
217
 
 
218
        pSD->colormapFocus = NULL;
 
219
        WmInstallColormap (pSD, pSD->workspaceColormap);
 
220
    }
 
221
 
 
222
} /* END OF FUNCTION ForceColormapFocus */
 
223
#endif
 
224
 
 
225
 
 
226
 
 
227
/*************************************<->*************************************
 
228
 *
 
229
 *  SetColormapFocus (pSD, pCD)
 
230
 *
 
231
 *
 
232
 *  Description:
 
233
 *  -----------
 
234
 *  This function is used to set the colormap focus to a particular client
 
235
 *  window or to clear the colormap focus (set focus to the root window).
 
236
 *
 
237
 *
 
238
 *  Inputs:
 
239
 *  ------
 
240
 *  pSD = pointer to Screen Data
 
241
 *  pCD = pointer to client data (clientColormap ...)
 
242
 *
 
243
 *************************************<->***********************************/
 
244
 
 
245
void SetColormapFocus (WmScreenData *pSD, ClientData *pCD)
 
246
{
 
247
    if (pCD == pSD->colormapFocus)
 
248
    {
 
249
        /*
 
250
         * The focus is already set to the right place.
 
251
         */
 
252
 
 
253
        return;
 
254
    }
 
255
#ifndef OLD_COLORMAP
 
256
    ForceColormapFocus (pSD, pCD);
 
257
#else /* OSF original */
 
258
 
 
259
    if (pCD && ((pCD->clientState == NORMAL_STATE) ||
 
260
                (pCD->clientState == MAXIMIZED_STATE)))
 
261
    {
 
262
        pSD->colormapFocus = pCD;
 
263
#ifndef OLD_COLORMAP /* colormaps */
 
264
        ProcessColormapList (pSD, pCD);
 
265
#else /* OSF original */
 
266
        WmInstallColormap (pSD, pCD->clientColormap);
 
267
#endif
 
268
    }
 
269
    else
 
270
    {
 
271
        /*
 
272
         * The default colormap is installed for minimized windows that have
 
273
         * the colormap focus.
 
274
         * !!! should colormaps be installed for icons with client      !!!
 
275
         * !!! icon windows?  should the client colormap be installed ? !!!
 
276
         */
 
277
 
 
278
        pSD->colormapFocus = NULL;
 
279
        WmInstallColormap (pSD, pSD->workspaceColormap);
 
280
    }
 
281
#endif
 
282
 
 
283
} /* END OF FUNCTION SetColormapFocus */
 
284
 
 
285
 
 
286
 
 
287
/*************************************<->*************************************
 
288
 *
 
289
 *  WmInstallColormap (pSD, colormap)
 
290
 *
 
291
 *
 
292
 *  Description:
 
293
 *  -----------
 
294
 *  This function installs colormaps for the window manager.  It trys to be
 
295
 *  intelligent and avoid unnecessary installations.  It assumes that no
 
296
 *  other program is installing colormaps.
 
297
 *
 
298
 *
 
299
 *  Inputs:
 
300
 *  ------
 
301
 *  pSD = ptr to screen data
 
302
 *  colormap = the id for the colormap to be installed
 
303
 *
 
304
 *************************************<->***********************************/
 
305
 
 
306
void WmInstallColormap (WmScreenData *pSD, Colormap colormap)
 
307
{
 
308
    /*
 
309
     * !!! this could be generalized to work better for systems that !!!
 
310
     * !!! support multiple installed colormaps                      !!!
 
311
     */
 
312
 
 
313
    if (colormap != pSD->lastInstalledColormap)
 
314
    {
 
315
        XInstallColormap (DISPLAY, colormap);
 
316
        pSD->lastInstalledColormap = colormap;
 
317
    }
 
318
 
 
319
} /* END OF FUNCTION WmInstallColormap */
 
320
 
 
321
 
 
322
 
 
323
/*************************************<->*************************************
 
324
 *
 
325
 *  ResetColormapData (pCD, pWindows, count)
 
326
 *
 
327
 *
 
328
 *  Description:
 
329
 *  -----------
 
330
 *  This function is used to release old colormap data (contexts, malloc'ed
 
331
 *  space).
 
332
 *
 
333
 *
 
334
 *  Inputs:
 
335
 *  ------
 
336
 *  pCD = pointer to client data (cmapWindows ...)
 
337
 *
 
338
 *  pWindows = new list of colormap windows
 
339
 *
 
340
 *  count = number of windows in new colormap windows list
 
341
 *
 
342
 *************************************<->***********************************/
 
343
 
 
344
void ResetColormapData (ClientData *pCD, Window *pWindows, int count)
 
345
{
 
346
    int i;
 
347
 
 
348
 
 
349
    if (pCD->clientCmapCount)
 
350
    {
 
351
        if (count == 0)
 
352
        {
 
353
            /* reset the client colormap to the toplevel window colormap */
 
354
            for (i = 0; i < pCD->clientCmapCount; i++)
 
355
            {
 
356
                if (pCD->cmapWindows[i] == pCD->client)
 
357
                {
 
358
                    pCD->clientColormap = pCD->clientCmapList[i];
 
359
                    break;
 
360
                }
 
361
            }
 
362
        }
 
363
 
 
364
        /*
 
365
         * Free up old contexts.
 
366
         */
 
367
 
 
368
        for (i = 0; i < pCD->clientCmapCount; i++)
 
369
        {
 
370
            if (pCD->cmapWindows[i] != pCD->client)
 
371
            {
 
372
#ifndef IBM_169380
 
373
                RemoveColormapWindowReference(pCD, pCD->cmapWindows[i]);
 
374
#else
 
375
                XDeleteContext (DISPLAY, pCD->cmapWindows[i],
 
376
                    wmGD.windowContextType);
 
377
#endif
 
378
            }
 
379
        }
 
380
 
 
381
        /*
 
382
         * Free up old colormap data.
 
383
         */
 
384
 
 
385
        XtFree ((char *)(pCD->cmapWindows));
 
386
        XtFree ((char *)(pCD->clientCmapList));
 
387
        pCD->clientCmapCount = 0;
 
388
#ifndef OLD_COLORMAP /* colormap */
 
389
        XtFree ((char  *)(pCD->clientCmapFlags));
 
390
        pCD->clientCmapFlags = 0;               /* DEBUG: */
 
391
        pCD->clientCmapFlagsInitialized = 0;
 
392
#endif
 
393
    }
 
394
 
 
395
    if (count)
 
396
    {
 
397
        /*
 
398
         * Set new contexts.
 
399
         */
 
400
 
 
401
        for (i = 0; i < count; i++)
 
402
        {
 
403
            if (pWindows[i] != pCD->client)
 
404
            {
 
405
#ifndef IBM_169380
 
406
                AddColormapWindowReference(pCD, pWindows[i]);
 
407
#else
 
408
                XSaveContext (DISPLAY, pWindows[i], wmGD.windowContextType,
 
409
                    (caddr_t)pCD);
 
410
#endif
 
411
            }
 
412
        }
 
413
    }
 
414
 
 
415
} /* END OF FUNCTION ResetColormapData */
 
416
 
 
417
#ifndef IBM_169380
 
418
/*************************************<->*************************************
 
419
 *
 
420
 *  AddColormapWindowReference (pCD, window)
 
421
 *
 
422
 *  Description:
 
423
 *  -----------
 
424
 *  This function is used to update (or create, if necessary) the structure
 
425
 *  that keeps track of all references to a Window from a toplevel window
 
426
 *  WM_COLORMAP_DATA property.
 
427
 *
 
428
 *************************************<->***********************************/
 
429
 
 
430
void AddColormapWindowReference (ClientData *pCD, Window window)
 
431
{
 
432
    ClientData          **cmap_window_data;
 
433
    Boolean             context_exists;
 
434
    int                 i;
 
435
    ClientData          **new_cmap_window_data;
 
436
 
 
437
    context_exists = (!XFindContext (DISPLAY, window,
 
438
                        wmGD.cmapWindowContextType,
 
439
                        (XPointer *) &cmap_window_data));
 
440
    if (context_exists)
 
441
    {
 
442
        for (i = 0; cmap_window_data[i] != NULL; i++)
 
443
        {
 
444
            if (cmap_window_data[i] == pCD)
 
445
            {
 
446
                /* Reference already exists - return */
 
447
                return;
 
448
            }
 
449
        }
 
450
        new_cmap_window_data = (ClientData **)
 
451
                                XtMalloc((i + 2 ) * sizeof(ClientData *));
 
452
        memcpy((void *)new_cmap_window_data,(void *)cmap_window_data,
 
453
                        (i + 1) * sizeof(ClientData *));
 
454
        XtFree((char *) cmap_window_data);
 
455
        XDeleteContext(DISPLAY, window, wmGD.cmapWindowContextType);
 
456
    }
 
457
    else
 
458
    {
 
459
        i = 0;
 
460
        new_cmap_window_data = (ClientData **)
 
461
                                XtMalloc(2 * sizeof(ClientData *));
 
462
    }
 
463
    new_cmap_window_data[i] = pCD;
 
464
    new_cmap_window_data[i + 1] = NULL;
 
465
    XSaveContext (DISPLAY, window, wmGD.cmapWindowContextType,
 
466
                        (caddr_t)new_cmap_window_data);
 
467
}
 
468
 
 
469
/*************************************<->*************************************
 
470
 *
 
471
 *  RemoveColormapWindowReference (pCD, window)
 
472
 *
 
473
 *  Description:
 
474
 *  -----------
 
475
 *  This function is used to update (or delete, if necessary) the structure
 
476
 *  that keeps track of all references to a Window from a toplevel window
 
477
 *  WM_COLORMAP_DATA property.
 
478
 *
 
479
 *************************************<->***********************************/
 
480
 
 
481
void RemoveColormapWindowReference (ClientData *pCD, Window window)
 
482
{
 
483
    ClientData  **cmap_window_data;
 
484
    Boolean     context_exists;
 
485
    int         i;
 
486
    int         reference_idx = -1;
 
487
    ClientData  **new_cmap_window_data;
 
488
 
 
489
    context_exists = (!XFindContext (DISPLAY, window,
 
490
                        wmGD.cmapWindowContextType,
 
491
                        (XPointer *) &cmap_window_data));
 
492
    if (context_exists)
 
493
    {
 
494
        for (i = 0; cmap_window_data[i] != NULL; i++)
 
495
        {
 
496
            if (cmap_window_data[i] == pCD)
 
497
                reference_idx = i;
 
498
        }
 
499
        if (reference_idx < 0)
 
500
            return;
 
501
 
 
502
        if (i > 1)
 
503
        {
 
504
        int     j,idx;
 
505
 
 
506
            new_cmap_window_data = (ClientData **)
 
507
                                        XtMalloc(i * sizeof(ClientData *));
 
508
            idx = 0;
 
509
            for (j = 0; cmap_window_data[j] != NULL; j++)
 
510
            {
 
511
                if (j != reference_idx)
 
512
                {
 
513
                    new_cmap_window_data[idx] = cmap_window_data[j];
 
514
                    idx++;
 
515
                }
 
516
            }
 
517
            new_cmap_window_data[idx] = NULL;
 
518
        }
 
519
        XtFree((char *) cmap_window_data);
 
520
        XDeleteContext(DISPLAY, window, wmGD.cmapWindowContextType);
 
521
        if (i > 1)
 
522
        {
 
523
            XSaveContext (DISPLAY, window,
 
524
                        wmGD.cmapWindowContextType,
 
525
                        (caddr_t)new_cmap_window_data);
 
526
        }
 
527
    }
 
528
}
 
529
#endif  /* IBM_169380 */
 
530
 
 
531
/*******************************************************************************
 
532
 **
 
533
 ** The rest of this module contains the SGI-added colormap handling.
 
534
 **
 
535
 ** mwm 1.1.3 didn't even try to deal with multiple colormaps, except to rotate
 
536
 ** them.  We need to see that all of the colormaps from WM_COLORMAP_WINDOWS
 
537
 ** are installed when a window gets colormap focus.
 
538
 **
 
539
 ** The general idea is to keep track of which colormaps bounce which other
 
540
 ** ones, so we only flash the first time (usually not even then).
 
541
 **
 
542
 ** The conflict record of a window is cleared whenever:
 
543
 **     * WM_COLORMAP_WINDOWS property changes
 
544
 **     * ColormapNotify for a new colormap happens
 
545
 **     * windows are rotated (prev_cmap, next_cmap)
 
546
 ** This is because with a changed colormap list, we need to recalculate
 
547
 ** which ones get bounced out during a full colormap installation.
 
548
 **
 
549
 ** We don't just lift the twm code because, after carefully looking over
 
550
 ** the twm code, it appears to have some problems of its own.  In
 
551
 ** particular, it assumes that if a given colormap displaces another one
 
552
 ** once, it will always do so.  This isn't necessarily so for a multiple
 
553
 ** hardware colormaps machine.
 
554
 **
 
555
 ** We still need to add code to keep track of which color maps are really
 
556
 ** installed at any one time.  The current code is ready for this, but it has
 
557
 ** not yet been done.  Then we could do two things:
 
558
 **
 
559
 **     * refrain from installing a colormap if it is already installed
 
560
 **
 
561
 **     * have a way to restore all installed colormaps after the window
 
562
 **       manager overwrites with it's own.
 
563
 **
 
564
 ******************************************************************************/
 
565
 
 
566
 
 
567
void
 
568
ProcessColormapList (WmScreenData *pSD, ClientData *pCD)
 
569
 
 
570
{
 
571
        register int i;
 
572
        XEvent event;
 
573
 
 
574
 
 
575
    /*
 
576
     * If there is no client, return.  This can happen when the root gets focus.
 
577
     */
 
578
        if (!pCD) return;
 
579
 
 
580
    /*
 
581
     * If the window does not have colormap focus, return.  We only install
 
582
     * colormaps for windows with focus.  We'll get another chance when the
 
583
     * window does get focus.
 
584
     */
 
585
        if (pCD != pSD->colormapFocus) return;
 
586
 
 
587
    /*
 
588
     * If window is iconified, return.
 
589
     */
 
590
        if (   (pCD->clientState != NORMAL_STATE) 
 
591
            && (pCD->clientState != MAXIMIZED_STATE)
 
592
           ) return;
 
593
 
 
594
    /*
 
595
     * If the list doesn't exist, or has just a single item, no conflicts
 
596
     * exist -- just go ahead and install the indicated colormap.
 
597
     */
 
598
        if (pCD->clientCmapCount == 0) {
 
599
                WmInstallColormap (pSD, pCD->clientColormap);
 
600
                return;
 
601
        }
 
602
        if (pCD->clientCmapCount == 1) {
 
603
                WmInstallColormap (pSD, pCD->clientCmapList[0]);
 
604
                return;
 
605
        }
 
606
 
 
607
    /*
 
608
     * If the list has already been initialized, we just need to do installs.
 
609
     * Separate out these loops for performance, and because it isn't nice
 
610
     * to grab the server unnecessarily.
 
611
     *
 
612
     * This code should also check for already-installed, once we put in that
 
613
     * capability.
 
614
     */
 
615
        if (pCD->clientCmapFlagsInitialized) {
 
616
 
 
617
            /* Do the part between the index and zero */
 
618
                for (i=pCD->clientCmapIndex; --i>=0; ) {
 
619
                        if (pCD->clientCmapFlags[i] == ColormapInstalled) {
 
620
                                WmInstallColormap (pSD, pCD->clientCmapList[i]);
 
621
                           }
 
622
                };
 
623
        
 
624
            /* Do the part from the end of the list to the index */
 
625
                for (i=pCD->clientCmapCount; --i>= pCD->clientCmapIndex; ) {
 
626
                        if (pCD->clientCmapFlags[i] == ColormapInstalled) {
 
627
                                WmInstallColormap (pSD, pCD->clientCmapList[i]);
 
628
                        }
 
629
                }
 
630
 
 
631
            /**/
 
632
                return;
 
633
        }
 
634
 
 
635
    /*
 
636
     * If we get this far, the list has not yet been initialized.
 
637
     *
 
638
     * Stabilize the input queue -- the issue is that we need to know
 
639
     * which colormap notify install and uninstall events are ours.
 
640
     */
 
641
        XGrabServer (DISPLAY);  /* Ensure no one else's events for awhile */
 
642
        XSync (DISPLAY, FALSE); /* Let pending events settle */
 
643
        firstRequest = NextRequest (DISPLAY); /* First one that can be ours */
 
644
 
 
645
    /*
 
646
     * Install the colormaps from last to first -- first is the "highest
 
647
     * priority".  "First" is pCD->clientCmapIndex.
 
648
     *
 
649
     * If the list has not been proocessed before, we need to unconditionally
 
650
     * install each colormap.  Colormap flashing is possible this once.
 
651
     *
 
652
     * If the list has already been processed once, all conflict checking
 
653
     * was done then.  All we need to do this time is to install the colormaps
 
654
     * we know we need.
 
655
     */
 
656
 
 
657
        /* Do the part between the index and zero */
 
658
        for (i=pCD->clientCmapIndex; --i>=0; ) {
 
659
                WmInstallColormap (pSD, pCD->clientCmapList[i]);
 
660
                pCD->clientCmapFlags[i] = ColormapInstalled;
 
661
        };
 
662
 
 
663
        /* Do the part from the end of the list to the index */
 
664
        for (i=pCD->clientCmapCount; --i>= pCD->clientCmapIndex; ) {
 
665
                WmInstallColormap (pSD, pCD->clientCmapList[i]);
 
666
                pCD->clientCmapFlags[i] = ColormapInstalled;
 
667
        }
 
668
 
 
669
    /*
 
670
     * Stabilize the input queue again -- the issue is that we need to know
 
671
     * which colormap notify install and uninstall events we caused.
 
672
     */
 
673
        XSync (DISPLAY, FALSE);                 /* Let pending events settle */
 
674
        lastRequest = NextRequest (DISPLAY);    /* Last one that can be ours */
 
675
        XUngrabServer (DISPLAY);                /* Let others use it again */
 
676
 
 
677
    /* Process the install & uninstall events */
 
678
        XCheckIfEvent (DISPLAY, (XEvent *) &event, ProcessEvents, (char *)pCD);
 
679
 
 
680
    /* Set that the list has been processed once */
 
681
        pCD->clientCmapFlagsInitialized = True;
 
682
}
 
683
 
 
684
 
 
685
/*
 
686
 * Look over the queue for install and uninstall events on colormap/window
 
687
 * combinations we care about.  We don't actually disturb the queue, so
 
688
 * events can be delivered in undisturbed order to the normal event handling
 
689
 * routines.
 
690
 *
 
691
 * For each appropriate install/uninstall ColormapNotify event that is queued:
 
692
 *         *) if uninstall event
 
693
 *              *) Set the conflict flag for this colormap window
 
694
 *         else if install event
 
695
 *              *) Clear the conflict flag for this colormap window
 
696
 */
 
697
static Bool
 
698
ProcessEvents(Display *dpy, XEvent *Event, char *c_pCD)
 
699
{
 
700
        int i;
 
701
        XColormapEvent *pEvent = (XColormapEvent *) Event;
 
702
        ClientData *pCD = (ClientData *) c_pCD;
 
703
 
 
704
        if (   (pEvent->type == ColormapNotify)
 
705
            && (pEvent->serial >= firstRequest)
 
706
            && (pEvent->serial <  lastRequest)
 
707
            && (pEvent->colormap != None)
 
708
            && (!pEvent->new)
 
709
           ) {
 
710
                switch (pEvent->state) {
 
711
                case ColormapInstalled:
 
712
                        for (i=0; i<pCD->clientCmapCount; i++) {
 
713
                                if (  (pCD->clientCmapList[i]==pEvent->colormap)
 
714
                                    &&(pCD->cmapWindows[i]==pEvent->window)
 
715
                                   ) {
 
716
                                        pCD->clientCmapFlags[i]
 
717
                                                = ColormapInstalled;
 
718
                                        break;
 
719
                                }
 
720
                        }
 
721
                        break;
 
722
                case ColormapUninstalled:
 
723
                        for (i=0; i<pCD->clientCmapCount; i++) {
 
724
                                if (  (pCD->clientCmapList[i]==pEvent->colormap)
 
725
                                    &&(pCD->cmapWindows[i]==pEvent->window)
 
726
                                   ) {
 
727
                                        pCD->clientCmapFlags[i]
 
728
                                                = ColormapUninstalled;
 
729
                                        break;
 
730
                                }
 
731
                        }
 
732
                        break;
 
733
                default:                /* Should never get here */
 
734
                        break;
 
735
                }
 
736
        }
 
737
 
 
738
    /*
 
739
     * Always return false:
 
740
     *  * so that we get to search the entire queue -- it isn't very long
 
741
     *  * so all events remain on the queue to be handled normally elsewhere
 
742
     */
 
743
        return False;   /* Always, so no events are lost from the queue */
 
744
}