summaryrefslogtreecommitdiff
path: root/src/Fl_visual.cxx
blob: 9709b18b3d384bae25322f9d06822a2a7588aba5 (plain)
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
//
// "$Id$"
//
// Visual support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2009 by Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems on the following page:
//
//     http://www.fltk.org/str.php
//

// Set the default visual according to passed switches:

#include <config.h>
#include <FL/Fl.H>
#include <FL/x.H>

/** \fn  Fl::visual(int flags)
    Selects a visual so that your graphics are drawn correctly.  This is
    only allowed before you call show() on any windows.  This does nothing
    if the default visual satisfies the capabilities, or if no visual
    satisfies the capabilities, or on systems that don't have such
    brain-dead notions.
    
    <P>Only the following combinations do anything useful:
    
    <UL>
    <LI>Fl::visual(FL_RGB)
    <BR>Full/true color (if there are several depths FLTK chooses  the
    largest).  Do this if you use fl_draw_image
    for much better (non-dithered)  output.
    <BR>&nbsp; </LI>
    <LI>Fl::visual(FL_RGB8)
    <BR>Full color with at least 24 bits of color. FL_RGB will
    always  pick this if available, but if not it will happily return a
    less-than-24 bit deep visual.  This call fails if 24 bits are not
    available.
    <BR>&nbsp; </LI>
    <LI>Fl::visual(FL_DOUBLE|FL_INDEX)
    <BR>Hardware double buffering.  Call this if you are going to use 
    Fl_Double_Window.
    <BR>&nbsp; </LI>
    <LI>Fl::visual(FL_DOUBLE|FL_RGB)</LI>
    <LI>Fl::visual(FL_DOUBLE|FL_RGB8)
    <BR>Hardware double buffering and full color.
    </UL>
    
    <P>This returns true if the system has the capabilities by default or
    FLTK suceeded in turing them on.  Your program will still work even if
    this returns false (it just won't look as good).
*/
#ifdef WIN32
int Fl::visual(int flags) {
  fl_GetDC(0);
  if (flags & FL_DOUBLE) return 0;
  if (!(flags & FL_INDEX) &&
    GetDeviceCaps(fl_gc,BITSPIXEL) <= 8) return 0;
  if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0;
  return 1;
}
#elif defined(__APPLE__)

// \todo Mac : need to implement Visual flags
int Fl::visual(int flags) {
  (void)flags;
  return 1;
}

#else

#if USE_XDBE
#include <X11/extensions/Xdbe.h>
#endif

static int test_visual(XVisualInfo& v, int flags) {
  if (v.screen != fl_screen) return 0;
#if USE_COLORMAP
  if (!(flags & FL_INDEX)) {
    if (v.c_class != StaticColor && v.c_class != TrueColor) return 0;
    if (v.depth <= 8) return 0; // fltk will work better in colormap mode
  }
  if (flags & FL_RGB8) {
    if (v.depth < 24) return 0;
  }
  // for now, fltk does not like colormaps of more than 8 bits:
  if ((v.c_class&1) && v.depth > 8) return 0;
#else
  // simpler if we can't use colormapped visuals at all:
  if (v.c_class != StaticColor && v.c_class != TrueColor) return 0;
#endif
#if USE_XDBE
  if (flags & FL_DOUBLE) {
    static XdbeScreenVisualInfo *xdbejunk;
    if (!xdbejunk) {
      int event_base, error_base;
      if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
      Drawable root = RootWindow(fl_display,fl_screen);
      int numscreens = 1;
      xdbejunk = XdbeGetVisualInfo(fl_display,&root,&numscreens);
      if (!xdbejunk) return 0;
    }
    for (int j = 0; ; j++) {
      if (j >= xdbejunk->count) return 0;
      if (xdbejunk->visinfo[j].visual == v.visualid) break;
    }
  }
#endif
  return 1;
}

int Fl::visual(int flags) {
#if USE_XDBE == 0
  if (flags & FL_DOUBLE) return 0;
#endif
  fl_open_display();
  // always use default if possible:
  if (test_visual(*fl_visual, flags)) return 1;
  // get all the visuals:
  XVisualInfo vTemplate;
  int num;
  XVisualInfo *visualList = XGetVisualInfo(fl_display, 0, &vTemplate, &num);
  // find all matches, use the one with greatest depth:
  XVisualInfo *found = 0;
  for (int i=0; i<num; i++) if (test_visual(visualList[i], flags)) {
    if (!found || found->depth < visualList[i].depth)
      found = &visualList[i];
  }
  if (!found) {XFree((void*)visualList); return 0;}
  fl_visual = found;
  fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
				fl_visual->visual, AllocNone);
  return 1;
}

#endif

//
// End of "$Id$".
//