ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/video_x.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/video_x.cpp (file contents):
Revision 1.52 by cebix, 2001-07-03T19:20:46Z vs.
Revision 1.53 by cebix, 2001-07-06T20:49:53Z

# Line 37 | Line 37
37   #include <sys/shm.h>
38   #include <errno.h>
39  
40 + #include <algorithm>
41 +
42 + #ifndef NO_STD_NAMESPACE
43 + using std::sort;
44 + #endif
45 +
46   #ifdef HAVE_PTHREADS
47   # include <pthread.h>
48   #endif
# Line 116 | Line 122 | static int keycode_table[256];                                         // X
122  
123   // X11 variables
124   static int screen;                                                                      // Screen number
119 static int xdepth;                                                                      // Depth of X screen
125   static Window rootwin;                                                          // Root window and our window
126 < static XVisualInfo visualInfo;
127 < static Visual *vis;
123 < static Colormap cmap[2] = {0, 0};                                       // Colormaps for indexed modes (DGA needs two of them)
126 > static int num_depths = 0;                                                      // Number of available X depths
127 > static int *avail_depths = NULL;                                        // List of available X depths
128   static XColor black, white;
129   static unsigned long black_pixel, white_pixel;
130   static int eventmask;
131  
132 + static int xdepth;                                                                      // Depth of X screen
133 + static XVisualInfo visualInfo;
134 + static Visual *vis;
135 + static int color_class;
136 +
137   static int rshift, rloss, gshift, gloss, bshift, bloss; // Pixel format of DirectColor/TrueColor modes
138  
139 + static Colormap cmap[2] = {0, 0};                                       // Colormaps for indexed modes (DGA needs two of them)
140 +
141   static XColor palette[256];                                                     // Color palette to be used as CLUT and gamma table
142   static bool palette_changed = false;                            // Flag: Palette changed, redraw thread must set new colors
143  
# Line 192 | Line 203 | static inline uint32 map_rgb(uint8 red,
203          return ((red >> rloss) << rshift) | ((green >> gloss) << gshift) | ((blue >> bloss) << bshift);
204   }
205  
206 + // Do we have a visual for handling the specified Mac depth? If so, set the
207 + // global variables "xdepth", "visualInfo", "vis" and "color_class".
208 + static bool find_visual_for_depth(video_depth depth)
209 + {
210 +        D(bug("have_visual_for_depth(%d)\n", 1 << depth));
211 +
212 +        // Calculate minimum and maximum supported X depth
213 +        int min_depth = 1, max_depth = 32;
214 +        switch (depth) {
215 +                case VDEPTH_1BIT:       // 1-bit works always
216 +                        min_depth = 1;
217 +                        max_depth = 32;
218 +                        break;
219 + #ifdef ENABLE_VOSF
220 +                case VDEPTH_2BIT:
221 +                case VDEPTH_4BIT:       // VOSF blitters can convert 2/4-bit -> 16/32-bit
222 +                        min_depth = 15;
223 +                        max_depth = 32;
224 +                        break;
225 +                case VDEPTH_8BIT:       // VOSF blitters can convert 8-bit -> 16/32-bit
226 +                        min_depth = 8;
227 +                        max_depth = 32;
228 +                        break;
229 + #else
230 +                case VDEPTH_2BIT:
231 +                case VDEPTH_4BIT:       // 2/4-bit requires VOSF blitters
232 +                        return false;
233 +                case VDEPTH_8BIT:       // 8-bit without VOSF requires an 8-bit visual
234 +                        min_depth = 8;
235 +                        max_depth = 8;
236 +                        break;
237 + #endif
238 +                case VDEPTH_16BIT:      // 16-bit requires a 15/16-bit visual
239 +                        min_depth = 15;
240 +                        max_depth = 16;
241 +                        break;
242 +                case VDEPTH_32BIT:      // 32-bit requires a 24/32-bit visual
243 +                        min_depth = 24;
244 +                        max_depth = 32;
245 +                        break;
246 +        }
247 +        D(bug(" minimum required X depth is %d, maximum supported X depth is %d\n", min_depth, max_depth));
248 +
249 +        // Try to find a visual for one of the color depths
250 +        bool visual_found = false;
251 +        for (int i=0; i<num_depths && !visual_found; i++) {
252 +
253 +                xdepth = avail_depths[i];
254 +                D(bug(" trying to find visual for depth %d\n", xdepth));
255 +                if (xdepth < min_depth || xdepth > max_depth)
256 +                        continue;
257 +
258 +                // Determine best color class for this depth
259 +                switch (xdepth) {
260 +                        case 1: // Try StaticGray or StaticColor
261 +                                if (XMatchVisualInfo(x_display, screen, xdepth, StaticGray, &visualInfo)
262 +                                 || XMatchVisualInfo(x_display, screen, xdepth, StaticColor, &visualInfo))
263 +                                        visual_found = true;
264 +                                break;
265 +                        case 8: // Need PseudoColor
266 +                                if (XMatchVisualInfo(x_display, screen, xdepth, PseudoColor, &visualInfo))
267 +                                        visual_found = true;
268 +                                break;
269 +                        case 15:
270 +                        case 16:
271 +                        case 24:
272 +                        case 32: // Try DirectColor first, as this will allow gamma correction
273 +                                if (XMatchVisualInfo(x_display, screen, xdepth, DirectColor, &visualInfo)
274 +                                 || XMatchVisualInfo(x_display, screen, xdepth, TrueColor, &visualInfo))
275 +                                        visual_found = true;
276 +                                break;
277 +                        default:
278 +                                D(bug("  not a supported depth\n"));
279 +                                break;
280 +                }
281 +        }
282 +        if (!visual_found)
283 +                return false;
284 +
285 +        // Visual was found
286 +        vis = visualInfo.visual;
287 +        color_class = visualInfo.c_class;
288 +        D(bug(" found visual ID 0x%02x, depth %d, class ", visualInfo.visualid, xdepth));
289 + #if DEBUG
290 +        switch (color_class) {
291 +                case StaticGray: D(bug("StaticGray\n")); break;
292 +                case GrayScale: D(bug("GrayScale\n")); break;
293 +                case StaticColor: D(bug("StaticColor\n")); break;
294 +                case PseudoColor: D(bug("PseudoColor\n")); break;
295 +                case TrueColor: D(bug("TrueColor\n")); break;
296 +                case DirectColor: D(bug("DirectColor\n")); break;
297 +        }
298 + #endif
299 + }
300 +
301   // Add mode to list of supported modes
302   static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth)
303   {
# Line 422 | Line 528 | void driver_base::update_palette(void)
528                  int num = 256;
529                  if (IsDirectMode(VideoMonitor.mode))
530                          num = vis->map_entries; // Palette is gamma table
531 <                else if (vis->c_class == DirectColor)
531 >                else if (color_class == DirectColor)
532                          return; // Indexed mode on true color screen, don't set CLUT
533                  XStoreColors(x_display, cmap[0], palette, num);
534                  XStoreColors(x_display, cmap[1], palette, num);
# Line 450 | Line 556 | driver_window::driver_window(const video
556          XSetWindowAttributes wattr;
557          wattr.event_mask = eventmask = win_eventmask;
558          wattr.background_pixel = black_pixel;
559 <        wattr.colormap = (mode.depth == VDEPTH_1BIT && vis->c_class == PseudoColor ? DefaultColormap(x_display, screen) : cmap[0]);
559 >        wattr.colormap = (mode.depth == VDEPTH_1BIT && color_class == PseudoColor ? DefaultColormap(x_display, screen) : cmap[0]);
560          w = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth,
561 <                InputOutput, vis, CWEventMask | CWBackPixel | (vis->c_class == PseudoColor || vis->c_class == DirectColor ? CWColormap : 0), &wattr);
561 >                InputOutput, vis, CWEventMask | CWBackPixel | (color_class == PseudoColor || color_class == DirectColor ? CWColormap : 0), &wattr);
562  
563          // Set window name/class
564          set_window_name(w, STR_WINDOW_TITLE);
# Line 1139 | Line 1245 | static void keycode_init(void)
1245   // Open display for specified mode
1246   static bool video_open(const video_mode &mode)
1247   {
1248 +        // Find best available X visual
1249 +        if (!find_visual_for_depth(mode.depth)) {
1250 +                ErrorAlert(STR_NO_XVISUAL_ERR);
1251 +                return false;
1252 +        }
1253 +
1254 +        // Create color maps
1255 +        if (color_class == PseudoColor || color_class == DirectColor) {
1256 +                cmap[0] = XCreateColormap(x_display, rootwin, vis, AllocAll);
1257 +                cmap[1] = XCreateColormap(x_display, rootwin, vis, AllocAll);
1258 +        }
1259 +
1260 +        // Find pixel format of direct modes
1261 +        if (color_class == DirectColor || color_class == TrueColor) {
1262 +                rshift = gshift = bshift = 0;
1263 +                rloss = gloss = bloss = 8;
1264 +                uint32 mask;
1265 +                for (mask=vis->red_mask; !(mask&1); mask>>=1)
1266 +                        ++rshift;
1267 +                for (; mask&1; mask>>=1)
1268 +                        --rloss;
1269 +                for (mask=vis->green_mask; !(mask&1); mask>>=1)
1270 +                        ++gshift;
1271 +                for (; mask&1; mask>>=1)
1272 +                        --gloss;
1273 +                for (mask=vis->blue_mask; !(mask&1); mask>>=1)
1274 +                        ++bshift;
1275 +                for (; mask&1; mask>>=1)
1276 +                        --bloss;
1277 +        }
1278 +
1279 +        // Preset palette pixel values for gamma table
1280 +        if (color_class == DirectColor) {
1281 +                int num = vis->map_entries;
1282 +                for (int i=0; i<num; i++) {
1283 +                        int c = (i * 256) / num;
1284 +                        palette[i].pixel = map_rgb(c, c, c);
1285 +                }
1286 +        }
1287 +
1288          // Load gray ramp to color map
1289 <        int num = (vis->c_class == DirectColor ? vis->map_entries : 256);
1289 >        int num = (color_class == DirectColor ? vis->map_entries : 256);
1290          for (int i=0; i<num; i++) {
1291                  int c = (i * 256) / num;
1292                  palette[i].red = c * 0x0101;
1293                  palette[i].green = c * 0x0101;
1294                  palette[i].blue = c * 0x0101;
1295 <                if (vis->c_class == PseudoColor)
1295 >                if (color_class == PseudoColor)
1296                          palette[i].pixel = i;
1297                  palette[i].flags = DoRed | DoGreen | DoBlue;
1298          }
# Line 1157 | Line 1303 | static bool video_open(const video_mode
1303  
1304   #ifdef ENABLE_VOSF
1305          // Load gray ramp to 8->16/32 expand map
1306 <        if (!IsDirectMode(mode) && (vis->c_class == TrueColor || vis->c_class == DirectColor))
1306 >        if (!IsDirectMode(mode) && (color_class == TrueColor || color_class == DirectColor))
1307                  for (int i=0; i<256; i++)
1308                          ExpandMap[i] = map_rgb(i, i, i);
1309   #endif
# Line 1249 | Line 1395 | bool VideoInit(bool classic)
1395          // Find screen and root window
1396          screen = XDefaultScreen(x_display);
1397          rootwin = XRootWindow(x_display, screen);
1398 <        
1399 <        // Get screen depth
1400 <        xdepth = DefaultDepth(x_display, screen);
1398 >
1399 >        // Get sorted list of available depths
1400 >        avail_depths = XListDepths(x_display, screen, &num_depths);
1401 >        if (avail_depths == NULL) {
1402 >                ErrorAlert(STR_UNSUPP_DEPTH_ERR);
1403 >                return false;
1404 >        }
1405 >        sort(avail_depths, avail_depths + num_depths);
1406          
1407   #ifdef ENABLE_FBDEV_DGA
1408          // Frame buffer name
# Line 1291 | Line 1442 | bool VideoInit(bool classic)
1442          black_pixel = BlackPixel(x_display, screen);
1443          white_pixel = WhitePixel(x_display, screen);
1444  
1294        // Get appropriate visual
1295        int color_class;
1296        switch (xdepth) {
1297                case 1:
1298                        color_class = StaticGray;
1299                        break;
1300                case 8:
1301                        color_class = PseudoColor;
1302                        break;
1303                case 15:
1304                case 16:
1305                case 24:
1306                case 32: // Try DirectColor first, as this will allow gamma correction
1307                        color_class = DirectColor;
1308                        if (!XMatchVisualInfo(x_display, screen, xdepth, color_class, &visualInfo))
1309                                color_class = TrueColor;
1310                        break;
1311                default:
1312                        ErrorAlert(STR_UNSUPP_DEPTH_ERR);
1313                        return false;
1314        }
1315        if (!XMatchVisualInfo(x_display, screen, xdepth, color_class, &visualInfo)) {
1316                ErrorAlert(STR_NO_XVISUAL_ERR);
1317                return false;
1318        }
1319        if (visualInfo.depth != xdepth) {
1320                ErrorAlert(STR_NO_XVISUAL_ERR);
1321                return false;
1322        }
1323        vis = visualInfo.visual;
1324
1325        // Create color maps
1326        if (color_class == PseudoColor || color_class == DirectColor) {
1327                cmap[0] = XCreateColormap(x_display, rootwin, vis, AllocAll);
1328                cmap[1] = XCreateColormap(x_display, rootwin, vis, AllocAll);
1329        }
1330
1331        // Find pixel format of direct modes
1332        if (color_class == DirectColor || color_class == TrueColor) {
1333                rshift = gshift = bshift = 0;
1334                rloss = gloss = bloss = 8;
1335                uint32 mask;
1336                for (mask=vis->red_mask; !(mask&1); mask>>=1)
1337                        ++rshift;
1338                for (; mask&1; mask>>=1)
1339                        --rloss;
1340                for (mask=vis->green_mask; !(mask&1); mask>>=1)
1341                        ++gshift;
1342                for (; mask&1; mask>>=1)
1343                        --gloss;
1344                for (mask=vis->blue_mask; !(mask&1); mask>>=1)
1345                        ++bshift;
1346                for (; mask&1; mask>>=1)
1347                        --bloss;
1348        }
1349
1350        // Preset palette pixel values for gamma table
1351        if (color_class == DirectColor) {
1352                int num = vis->map_entries;
1353                for (int i=0; i<num; i++) {
1354                        int c = (i * 256) / num;
1355                        palette[i].pixel = map_rgb(c, c, c);
1356                }
1357        }
1358
1445          // Get screen mode from preferences
1446          const char *mode_str;
1447          if (classic_mode)
# Line 1390 | Line 1476 | bool VideoInit(bool classic)
1476                  default_height = DisplayHeight(x_display, screen);
1477  
1478          // Mac screen depth follows X depth
1479 <        video_depth default_depth = DepthModeForPixelDepth(xdepth);
1479 >        video_depth default_depth = VDEPTH_1BIT;
1480 >        switch (DefaultDepth(x_display, screen)) {
1481 >                case 8:
1482 >                        default_depth = VDEPTH_8BIT;
1483 >                        break;
1484 >                case 15: case 16:
1485 >                        default_depth = VDEPTH_16BIT;
1486 >                        break;
1487 >                case 24: case 32:
1488 >                        default_depth = VDEPTH_32BIT;
1489 >                        break;
1490 >        }
1491  
1492          // Construct list of supported modes
1493          if (display_type == DISPLAY_WINDOW) {
1494                  if (classic)
1495                          add_mode(512, 342, 0x80, 64, VDEPTH_1BIT);
1496                  else {
1497 <                        if (default_depth != VDEPTH_1BIT)
1498 <                                add_window_modes(VDEPTH_1BIT);  // 1-bit modes are always available
1499 < #ifdef ENABLE_VOSF
1403 <                        if (default_depth > VDEPTH_8BIT) {
1404 <                                add_window_modes(VDEPTH_2BIT);  // 2, 4 and 8-bit modes are also possible on 16/32-bit screens with VOSF blitters
1405 <                                add_window_modes(VDEPTH_4BIT);
1406 <                                add_window_modes(VDEPTH_8BIT);
1497 >                        for (unsigned d=VDEPTH_1BIT; d<=VDEPTH_32BIT; d++) {
1498 >                                if (find_visual_for_depth(video_depth(d)))
1499 >                                        add_window_modes(video_depth(d));
1500                          }
1408 #endif
1409                        add_window_modes(default_depth);
1501                  }
1502          } else
1503                  add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth);
1504 +        if (VideoModes.empty()) {
1505 +                ErrorAlert(STR_NO_XVISUAL_ERR);
1506 +                return false;
1507 +        }
1508          video_init_depth_list();
1509  
1510 + #if DEBUG
1511 +        D(bug("Available video modes:\n"));
1512 +        vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
1513 +        while (i != end) {
1514 +                int bits = 1 << i->depth;
1515 +                if (bits == 16)
1516 +                        bits = 15;
1517 +                else if (bits == 32)
1518 +                        bits = 24;
1519 +                D(bug(" %dx%d (ID %02x), %d colors\n", i->x, i->y, i->resolution_id, 1 << bits));
1520 +                ++i;
1521 +        }
1522 + #endif
1523 +
1524          // Find requested default mode and open display
1525          if (VideoModes.size() == 1)
1526                  return video_open(VideoModes[0]);
# Line 1467 | Line 1576 | static void video_close(void)
1576          // Close display
1577          delete drv;
1578          drv = NULL;
1470 }
1471
1472 void VideoExit(void)
1473 {
1474        // Close display
1475        video_close();
1579  
1580          // Free colormaps
1581          if (cmap[0]) {
# Line 1483 | Line 1586 | void VideoExit(void)
1586                  XFreeColormap(x_display, cmap[1]);
1587                  cmap[1] = 0;
1588          }
1589 + }
1590 +
1591 + void VideoExit(void)
1592 + {
1593 +        // Close display
1594 +        video_close();
1595  
1596   #ifdef ENABLE_XF86_VIDMODE
1597          // Free video mode list
# Line 1499 | Line 1608 | void VideoExit(void)
1608                  fbdev_fd = -1;
1609          }
1610   #endif
1611 +
1612 +        // Free depth list
1613 +        if (avail_depths) {
1614 +                XFree(avail_depths);
1615 +                avail_depths = NULL;
1616 +        }
1617   }
1618  
1619  
# Line 1550 | Line 1665 | void video_set_palette(uint8 *pal, int n
1665                  p->red = pal[c*3 + 0] * 0x0101;
1666                  p->green = pal[c*3 + 1] * 0x0101;
1667                  p->blue = pal[c*3 + 2] * 0x0101;
1668 <                if (vis->c_class == PseudoColor)
1668 >                if (color_class == PseudoColor)
1669                          p->pixel = i;
1670                  p->flags = DoRed | DoGreen | DoBlue;
1671                  p++;
# Line 1558 | Line 1673 | void video_set_palette(uint8 *pal, int n
1673  
1674   #ifdef ENABLE_VOSF
1675          // Recalculate pixel color expansion map
1676 <        if (!IsDirectMode(VideoMonitor.mode) && (vis->c_class == TrueColor || vis->c_class == DirectColor)) {
1676 >        if (!IsDirectMode(VideoMonitor.mode) && (color_class == TrueColor || color_class == DirectColor)) {
1677                  for (int i=0; i<256; i++) {
1678                          int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier)
1679                          ExpandMap[i] = map_rgb(pal[c*3+0], pal[c*3+1], pal[c*3+2]);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines