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.12 by cebix, 1999-11-03T21:04:23Z vs.
Revision 1.13 by cebix, 2000-02-11T17:20:44Z

# Line 68 | Line 68 | enum {
68          DISPLAY_DGA             // DGA fullscreen display
69   };
70  
71
71   // Constants
72   const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes";
73   const char FBDEVICES_FILE_NAME[] = DATADIR "/fbdevices";
# Line 128 | Line 127 | static GC cursor_gc, cursor_mask_gc;
127   static uint8 *the_buffer_copy = NULL;                           // Copy of Mac frame buffer
128   static uint8 the_cursor[64];                                            // Cursor image data
129   static bool have_shm = false;                                           // Flag: SHM extensions available
130 + static bool updt_box[17][17];                                           // Flag for Update
131 + static int nr_boxes;
132 + static const int sm_uptd[] = {4,1,6,3,0,5,2,7};
133 + static int sm_no_boxes[] = {1,8,32,64,128,300};
134  
135   // Variables for XF86 DGA mode
136   static int current_dga_cmap;                                            // Number (0 or 1) of currently installed DGA colormap
# Line 214 | Line 217 | static int error_handler(Display *d, XEr
217   // Init window mode
218   static bool init_window(int width, int height)
219   {
220 +        int aligned_width = (width + 15) & ~15;
221 +        int aligned_height = (height + 15) & ~15;
222 +
223          // Set absolute mouse mode
224          ADBSetRelMouseMode(false);
225  
# Line 227 | Line 233 | static bool init_window(int width, int h
233          wattr.event_mask = eventmask = win_eventmask;
234          wattr.background_pixel = black_pixel;
235          wattr.border_pixel = black_pixel;
236 <        wattr.backing_store = Always;
236 >        wattr.backing_store = NotUseful;
237 >        wattr.save_under = false;
238          wattr.backing_planes = xdepth;
239  
240          XSync(x_display, false);
# Line 263 | Line 270 | static bool init_window(int width, int h
270  
271                  // Create SHM image ("height + 2" for safety)
272                  img = XShmCreateImage(x_display, vis, depth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height);
273 <                shminfo.shmid = shmget(IPC_PRIVATE, (height + 2) * img->bytes_per_line, IPC_CREAT | 0777);
274 <                the_buffer = (uint8 *)shmat(shminfo.shmid, 0, 0);
275 <                shminfo.shmaddr = img->data = (char *)the_buffer;
273 >                shminfo.shmid = shmget(IPC_PRIVATE, (aligned_height + 2) * img->bytes_per_line, IPC_CREAT | 0777);
274 >                the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0);
275 >                shminfo.shmaddr = img->data = (char *)the_buffer_copy;
276                  shminfo.readOnly = False;
277  
278                  // Try to attach SHM image, catching errors
# Line 286 | Line 293 | static bool init_window(int width, int h
293          
294          // Create normal X image if SHM doesn't work ("height + 2" for safety)
295          if (!have_shm) {
296 <                int bytes_per_row = width;
296 >                int bytes_per_row = aligned_width;
297                  switch (depth) {
298                          case 1:
299                                  bytes_per_row /= 8;
# Line 300 | Line 307 | static bool init_window(int width, int h
307                                  bytes_per_row *= 4;
308                                  break;
309                  }
310 <                the_buffer = (uint8 *)malloc((height + 2) * bytes_per_row);
311 <                img = XCreateImage(x_display, vis, depth, depth == 1 ? XYBitmap : ZPixmap, 0, (char *)the_buffer, width, height, 32, bytes_per_row);
310 >                the_buffer_copy = (uint8 *)malloc((aligned_height + 2) * bytes_per_row);
311 >                img = XCreateImage(x_display, vis, depth, depth == 1 ? XYBitmap : ZPixmap, 0, (char *)the_buffer_copy, aligned_width, aligned_height, 32, bytes_per_row);
312          }
313  
314          // 1-Bit mode is big-endian
# Line 311 | Line 318 | static bool init_window(int width, int h
318          }
319  
320          // Allocate memory for frame buffer copy
321 <        the_buffer_copy = (uint8 *)malloc((height + 2) * img->bytes_per_line);
321 >        the_buffer = (uint8 *)malloc((aligned_height + 2) * img->bytes_per_line);
322  
323          // Create GC
324          the_gc = XCreateGC(x_display, the_win, 0, 0);
325          XSetState(x_display, the_gc, black_pixel, white_pixel, GXcopy, AllPlanes);
326  
327 <        // Create cursor
328 <        cursor_image = XCreateImage(x_display, vis, 1, XYPixmap, 0, (char *)the_cursor, 16, 16, 16, 2);
329 <        cursor_image->byte_order = MSBFirst;
330 <        cursor_image->bitmap_bit_order = MSBFirst;
331 <        cursor_mask_image = XCreateImage(x_display, vis, 1, XYPixmap, 0, (char *)the_cursor+32, 16, 16, 16, 2);
332 <        cursor_mask_image->byte_order = MSBFirst;
326 <        cursor_mask_image->bitmap_bit_order = MSBFirst;
327 <        cursor_map = XCreatePixmap(x_display, the_win, 16, 16, 1);
328 <        cursor_mask_map = XCreatePixmap(x_display, the_win, 16, 16, 1);
329 <        cursor_gc = XCreateGC(x_display, cursor_map, 0, 0);
330 <        cursor_mask_gc = XCreateGC(x_display, cursor_mask_map, 0, 0);
331 <        mac_cursor = XCreatePixmapCursor(x_display, cursor_map, cursor_mask_map, &black, &white, 0, 0);
327 >        // Create no_cursor
328 >        mac_cursor = XCreatePixmapCursor (x_display,
329 >                                           XCreatePixmap (x_display, the_win, 1, 1, 1),
330 >                                           XCreatePixmap (x_display, the_win, 1, 1, 1),
331 >                                           &black, &white, 0, 0);
332 >        XDefineCursor (x_display, the_win, mac_cursor);
333  
334          // Set VideoMonitor
335   #ifdef WORDS_BIGENDIAN
# Line 844 | Line 845 | void VideoExit(void)
845                          close(fbdev_fd);
846                  }
847   #endif
847                
848                if (the_buffer_copy) {
849                        free(the_buffer_copy);
850                        the_buffer_copy = NULL;
851                }
848  
849                  XFlush(x_display);
850                  XSync(x_display, false);
# Line 856 | Line 852 | void VideoExit(void)
852                          XFreeColormap(x_display, cmap[0]);
853                          XFreeColormap(x_display, cmap[1]);
854                  }
855 +
856 +                if (the_buffer) {
857 +                        free(the_buffer);
858 +                        the_buffer = NULL;
859 +                }
860 +
861 +                if (!have_shm && the_buffer_copy) {
862 +                        free(the_buffer_copy);
863 +                        the_buffer_copy = NULL;
864 +                }
865          }
866   }
867  
# Line 1261 | Line 1267 | static void handle_events(void)
1267  
1268                          // Hidden parts exposed, force complete refresh of window
1269                          case Expose:
1270 <                                if (display_type == DISPLAY_WINDOW)
1271 <                                        memset(the_buffer_copy, 0, VideoMonitor.bytes_per_row * VideoMonitor.y);
1270 >                                if (display_type == DISPLAY_WINDOW) {
1271 >                                        int x1, y1;
1272 >                                        for (y1=0; y1<16; y1++)
1273 >                                        for (x1=0; x1<16; x1++)
1274 >                                                updt_box[x1][y1] = true;
1275 >                                        nr_boxes = 16 * 16;
1276 >                                }
1277                                  break;
1278                  }
1279          }
# Line 1273 | Line 1284 | static void handle_events(void)
1284   *  Window display update
1285   */
1286  
1287 < static void update_display(void)
1287 > static void update_display(int ticker)
1288   {
1289 <        // In classic mode, copy the frame buffer from Mac RAM
1290 <        if (classic_mode)
1291 <                Mac2Host_memcpy(the_buffer, 0x3fa700, VideoMonitor.bytes_per_row * VideoMonitor.y);
1281 <        
1282 <        // Incremental update code
1283 <        int wide = 0, high = 0, x1, x2, y1, y2, i, j;
1289 >        int y1, y2, y2s, y2a, i, x1, xm, xmo, ymo, yo, yi, yil, xic, xicl, xi;
1290 >        int xil = 0;
1291 >        int rxm = 0, rxmo = 0;
1292          int bytes_per_row = VideoMonitor.bytes_per_row;
1293          int bytes_per_pixel = VideoMonitor.bytes_per_row / VideoMonitor.x;
1294 <        uint8 *p, *p2;
1295 <
1296 <        // Check for first line from top and first line from bottom that have changed
1297 <        y1 = 0;
1298 <        for (j=0; j<VideoMonitor.y; j++) {
1299 <                if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) {
1300 <                        y1 = j;
1294 >        int rx = VideoMonitor.bytes_per_row / 16;
1295 >        int ry = VideoMonitor.y / 16;
1296 >        int max_box;
1297 >
1298 >        y2s = sm_uptd[ticker % 8];
1299 >        y2a = 8;
1300 >        for (i = 0; i < 6; i++)
1301 >                if (ticker % (2 << i))
1302                          break;
1303 <                }
1295 <        }
1296 <        y2 = y1 - 1;
1297 <        for (j=VideoMonitor.y-1; j>=y1; j--) {
1298 <                if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) {
1299 <                        y2 = j;
1300 <                        break;
1301 <                }
1302 <        }
1303 <        high = y2 - y1 + 1;
1303 >        max_box = sm_no_boxes[i];
1304  
1305 <        // Check for first column from left and first column from right that have changed
1306 <        if (high) {
1307 <                if (depth == 1) {
1308 <                        x1 = VideoMonitor.x;
1309 <                        for (j=y1; j<=y2; j++) {
1310 <                                p = &the_buffer[j * bytes_per_row];
1311 <                                p2 = &the_buffer_copy[j * bytes_per_row];
1312 <                                for (i=0; i<(x1>>3); i++) {
1313 <                                        if (*p != *p2) {
1314 <                                                x1 = i << 3;
1315 <                                                break;
1316 <                                        }
1317 <                                        p++;
1318 <                                        p2++;
1319 <                                }
1320 <                        }
1321 <                        x2 = x1;
1322 <                        for (j=y1; j<=y2; j++) {
1323 <                                p = &the_buffer[j * bytes_per_row];
1324 <                                p2 = &the_buffer_copy[j * bytes_per_row];
1325 <                                p += bytes_per_row;
1326 <                                p2 += bytes_per_row;
1327 <                                for (i=(VideoMonitor.x>>3); i>(x2>>3); i--) {
1328 <                                        p--;
1329 <                                        p2--;
1330 <                                        if (*p != *p2) {
1331 <                                                x2 = i << 3;
1332 <                                                break;
1305 >        if (y2a) {
1306 >                for (y1=0; y1<16; y1++) {
1307 >                        for (y2=y2s; y2 < ry; y2 += y2a) {
1308 >                                i = ((y1 * ry) + y2) * bytes_per_row;
1309 >                                for (x1=0; x1<16; x1++, i += rx) {
1310 >                                        if (updt_box[x1][y1] == false) {
1311 >                                                if (memcmp(&the_buffer_copy[i], &the_buffer[i], rx)) {
1312 >                                                        updt_box[x1][y1] = true;
1313 >                                                        nr_boxes++;
1314 >                                                }
1315                                          }
1316                                  }
1317                          }
1318 <                        wide = x2 - x1;
1318 >                }
1319 >        }
1320  
1321 <                        // Update copy of the_buffer
1322 <                        if (high && wide) {
1323 <                                for (j=y1; j<=y2; j++) {
1324 <                                        i = j * bytes_per_row + (x1 >> 3);
1325 <                                        memcpy(&the_buffer_copy[i], &the_buffer[i], wide >> 3);
1321 >        if ((nr_boxes <= max_box) && (nr_boxes)) {
1322 >                for (y1=0; y1<16; y1++) {
1323 >                        for (x1=0; x1<16; x1++) {
1324 >                                if (updt_box[x1][y1] == true) {
1325 >                                        if (rxm == 0)
1326 >                                                xm = x1;
1327 >                                        rxm += rx;
1328 >                                        updt_box[x1][y1] = false;
1329                                  }
1330 <                        }
1331 <
1332 <                } else {
1333 <                        x1 = VideoMonitor.x;
1334 <                        for (j=y1; j<=y2; j++) {
1335 <                                p = &the_buffer[j * bytes_per_row];
1336 <                                p2 = &the_buffer_copy[j * bytes_per_row];
1337 <                                for (i=0; i<x1; i++) {
1338 <                                        if (memcmp(p, p2, bytes_per_pixel)) {
1339 <                                                x1 = i;
1340 <                                                break;
1330 >                                if (((updt_box[x1+1][y1] == false) || (x1 == 15)) && (rxm)) {
1331 >                                        if ((rxmo != rxm) || (xmo != xm) || (yo != y1 - 1)) {
1332 >                                                if (rxmo) {
1333 >                                                        xi = xmo * rx;
1334 >                                                        yi = ymo * ry;
1335 >                                                        xil = rxmo;
1336 >                                                        yil = (yo - ymo +1) * ry;
1337 >                                                }
1338 >                                                rxmo = rxm;
1339 >                                                xmo = xm;
1340 >                                                ymo = y1;
1341                                          }
1342 <                                        p += bytes_per_pixel;
1343 <                                        p2 += bytes_per_pixel;
1344 <                                }
1345 <                        }
1346 <                        x2 = x1;
1347 <                        for (j=y1; j<=y2; j++) {
1348 <                                p = &the_buffer[j * bytes_per_row];
1349 <                                p2 = &the_buffer_copy[j * bytes_per_row];
1350 <                                p += bytes_per_row;
1351 <                                p2 += bytes_per_row;
1352 <                                for (i=VideoMonitor.x; i>x2; i--) {
1353 <                                        p -= bytes_per_pixel;
1354 <                                        p2 -= bytes_per_pixel;
1355 <                                        if (memcmp(p, p2, bytes_per_pixel)) {
1356 <                                                x2 = i;
1357 <                                                break;
1342 >                                        rxm = 0;
1343 >                                        yo = y1;
1344 >                                }      
1345 >                                if (xil) {
1346 >                                        i = (yi * bytes_per_row) + xi;
1347 >                                        for (y2=0; y2 < yil; y2++, i += bytes_per_row)
1348 >                                                memcpy(&the_buffer_copy[i], &the_buffer[i], xil);
1349 >                                        if (depth == 1) {
1350 >                                                if (have_shm)
1351 >                                                        XShmPutImage(x_display, the_win, the_gc, img, xi * 8, yi, xi * 8, yi, xil * 8, yil, 0);
1352 >                                                else
1353 >                                                        XPutImage(x_display, the_win, the_gc, img, xi * 8, yi, xi * 8, yi, xil * 8, yil);
1354 >                                        } else {
1355 >                                                if (have_shm)
1356 >                                                        XShmPutImage(x_display, the_win, the_gc, img, xi / bytes_per_pixel, yi, xi / bytes_per_pixel, yi, xil / bytes_per_pixel, yil, 0);
1357 >                                                else
1358 >                                                        XPutImage(x_display, the_win, the_gc, img, xi / bytes_per_pixel, yi, xi / bytes_per_pixel, yi, xil / bytes_per_pixel, yil);
1359                                          }
1360 +                                        xil = 0;
1361                                  }
1362 <                        }
1363 <                        wide = x2 - x1;
1364 <
1365 <                        // Update copy of the_buffer
1366 <                        if (high && wide) {
1367 <                                for (j=y1; j<=y2; j++) {
1368 <                                        i = j * bytes_per_row + x1 * bytes_per_pixel;
1381 <                                        memcpy(&the_buffer_copy[i], &the_buffer[i], bytes_per_pixel * wide);
1362 >                                if ((x1 == 15) && (y1 == 15) && (rxmo)) {
1363 >                                        x1--;
1364 >                                        xi = xmo * rx;
1365 >                                        yi = ymo * ry;
1366 >                                        xil = rxmo;
1367 >                                        yil = (yo - ymo +1) * ry;
1368 >                                        rxmo = 0;
1369                                  }
1370                          }
1371                  }
1372 <        }
1386 <
1387 <        // Refresh display
1388 <        if (high && wide) {
1389 <                if (have_shm)
1390 <                        XShmPutImage(x_display, the_win, the_gc, img, x1, y1, x1, y1, wide, high, 0);
1391 <                else
1392 <                        XPutImage(x_display, the_win, the_gc, img, x1, y1, x1, y1, wide, high);
1393 <        }
1394 <
1395 <        // Has the Mac started? (cursor data is not valid otherwise)
1396 <        if (HasMacStarted()) {
1397 <
1398 <                // Set new cursor image if it was changed
1399 <                if (memcmp(the_cursor, Mac2HostAddr(0x844), 64)) {
1400 <                        Mac2Host_memcpy(the_cursor, 0x844, 64);
1401 <                        memcpy(cursor_image->data, the_cursor, 32);
1402 <                        memcpy(cursor_mask_image->data, the_cursor+32, 32);
1403 <                        XFreeCursor(x_display, mac_cursor);
1404 <                        XPutImage(x_display, cursor_map, cursor_gc, cursor_image, 0, 0, 0, 0, 16, 16);
1405 <                        XPutImage(x_display, cursor_mask_map, cursor_mask_gc, cursor_mask_image, 0, 0, 0, 0, 16, 16);
1406 <                        mac_cursor = XCreatePixmapCursor(x_display, cursor_map, cursor_mask_map, &black, &white, ReadMacInt8(0x885), ReadMacInt8(0x887));
1407 <                        XDefineCursor(x_display, the_win, mac_cursor);
1408 <                }
1372 >                nr_boxes = 0;
1373          }
1374   }
1375  
# Line 1475 | Line 1439 | static void *redraw_func(void *arg)
1439                  }
1440                  pthread_mutex_unlock(&palette_lock);
1441  
1442 <                // In window mode, update display and mouse pointer
1442 >                // In window mode, update display
1443                  if (display_type == DISPLAY_WINDOW) {
1444                          tick_counter++;
1445 <                        if (tick_counter >= frame_skip) {
1482 <                                tick_counter = 0;
1483 <                                update_display();
1484 <                        }
1445 >                        update_display(tick_counter);
1446                  }
1447          }
1448          return NULL;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines