Пример #1
0
void
VGLSetXY(VGLBitmap *object, int x, int y, u_long color)
{
  int offset, soffset, undermouse;

  VGLCheckSwitch();
  if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) {
    if (object == VGLDisplay) {
      undermouse = VGLMouseFreezeXY(x, y);
      VGLSetXY(&VGLVDisplay, x, y, color);
    } else if (object->Type != MEMBUF)
      return;		/* invalid */
    else
      undermouse = 0;
    if (!undermouse) {
      offset = (y * object->VXsize + x) * object->PixelBytes;
      switch (object->Type) {
      case VIDBUF8S:
      case VIDBUF16S:
      case VIDBUF32S:
        offset = VGLSetSegment(offset);
        /* FALLTHROUGH */
      case MEMBUF:
      case VIDBUF8:
      case VIDBUF16:
      case VIDBUF24:
      case VIDBUF32:
        color = htole32(color);
        switch (object->PixelBytes) {
        case 1:
          memcpy(&object->Bitmap[offset], &color, 1);
          break;
        case 2:
          memcpy(&object->Bitmap[offset], &color, 2);
          break;
        case 3:
          memcpy(&object->Bitmap[offset], &color, 3);
          break;
        case 4:
          memcpy(&object->Bitmap[offset], &color, 4);
          break;
        }
        break;
      case VIDBUF24S:
        soffset = VGLSetSegment(offset);
        color = htole32(color);
        switch (VGLAdpInfo.va_window_size - soffset) {
        case 1:
          memcpy(&object->Bitmap[soffset], &color, 1);
          soffset = VGLSetSegment(offset + 1);
          memcpy(&object->Bitmap[soffset], (byte *)&color + 1, 2);
          break;
        case 2:
          memcpy(&object->Bitmap[soffset], &color, 2);
          soffset = VGLSetSegment(offset + 2);
          memcpy(&object->Bitmap[soffset], (byte *)&color + 2, 1);
          break;
        default:
          memcpy(&object->Bitmap[soffset], &color, 3);
          break;
        }
        break;
      case VIDBUF8X:
        outb(0x3c4, 0x02);
        outb(0x3c5, 0x01 << (x&0x3));
	object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)] = ((byte)color);
	break;
      case VIDBUF4S:
	offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8);
	goto set_planar;
      case VIDBUF4:
	offset = y*VGLAdpInfo.va_line_width + x/8;
set_planar:
        outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
        outb(0x3ce, 0x00); outb(0x3cf, (byte)color & 0x0f);	/* set/reset */
        outb(0x3ce, 0x01); outb(0x3cf, 0x0f);		/* set/reset enable */
        outb(0x3ce, 0x08); outb(0x3cf, 0x80 >> (x%8));	/* bit mask */
	object->Bitmap[offset] |= (byte)color;
      }
    }
    if (object == VGLDisplay)
      VGLMouseUnFreeze();
  }
Пример #2
0
void
VGLCheckSwitch(void)
{
  if (VGLAbortPending) {
    VGLEnd();
    exit(0);
  }
  while (VGLSwitchPending) {
    unsigned int offset;
    unsigned int len;
    int i;

    VGLSwitchPending = 0;
    if (VGLOnDisplay) {
      ioctl(0, KDENABIO, 0);
      ioctl(0, KDSETMODE, KD_GRAPHICS);
      ioctl(0, VGLMode, 0);
      VGLCurWindow = 0;
      VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE,
			   MAP_FILE, 0, 0);

      /* XXX: what if mmap() has failed! */
      VGLDisplay->Type = VIDBUF8;	/* XXX */
      switch (VGLModeInfo.vi_mem_model) {
      case V_INFO_MM_PLANAR:
	if (VGLModeInfo.vi_depth == 4 && VGLModeInfo.vi_planes == 4) {
	  if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size)
	    VGLDisplay->Type = VIDBUF4S;
	  else
	    VGLDisplay->Type = VIDBUF4;
	} else {
	  /* shouldn't be happening */
	}
        break;
      case V_INFO_MM_PACKED:
	if (VGLModeInfo.vi_depth == 8) {
	  if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size)
	    VGLDisplay->Type = VIDBUF8S;
	  else
	    VGLDisplay->Type = VIDBUF8;
	} else {
	  /* shouldn't be happening */
	}
        break;
      case V_INFO_MM_VGAX:
	VGLDisplay->Type = VIDBUF8X;
	break;
      default:
	/* shouldn't be happening */
        break;
      }

      VGLDisplay->Bitmap = VGLMem;
      VGLDisplay->Xsize = VGLModeInfo.vi_width;
      VGLDisplay->Ysize = VGLModeInfo.vi_height;
      VGLSetVScreenSize(VGLDisplay, VGLDisplay->VXsize, VGLDisplay->VYsize);
      VGLPanScreen(VGLDisplay, VGLDisplay->Xorigin, VGLDisplay->Yorigin);
      switch (VGLDisplay->Type) {
      case VIDBUF4S:
	outb(0x3c6, 0xff);
	outb(0x3ce, 0x01); outb(0x3cf, 0x00);		/* set/reset enable */
	outb(0x3ce, 0x08); outb(0x3cf, 0xff);		/* bit mask */
	for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes;
	     offset += len) {
	  VGLSetSegment(offset);
	  len = min(VGLBufSize/VGLModeInfo.vi_planes - offset,
		    VGLAdpInfo.va_window_size);
	  for (i = 0; i < VGLModeInfo.vi_planes; i++) {
	    outb(0x3c4, 0x02);
	    outb(0x3c5, 0x01<<i);
	    bcopy(&VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset],
		  VGLMem, len);
	  }
	}
	break;
      case VIDBUF4:
      case VIDBUF8X:
	outb(0x3c6, 0xff);
	outb(0x3ce, 0x01); outb(0x3cf, 0x00);		/* set/reset enable */
	outb(0x3ce, 0x08); outb(0x3cf, 0xff);		/* bit mask */
	for (i = 0; i < VGLModeInfo.vi_planes; i++) {
	  outb(0x3c4, 0x02);
	  outb(0x3c5, 0x01<<i);
	  bcopy(&VGLBuf[i*VGLAdpInfo.va_window_size], VGLMem,
		VGLAdpInfo.va_window_size);
	}
	break;
      case VIDBUF8:
      case VIDBUF8S:
	for (offset = 0; offset < VGLBufSize; offset += len) {
	  VGLSetSegment(offset);
	  len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size);
          bcopy(&VGLBuf[offset], VGLMem, len);
	}
	break;
      }
      VGLRestorePalette();
      ioctl(0, VT_RELDISP, VT_ACKACQ);
    }
    else {
      switch (VGLDisplay->Type) {
      case VIDBUF4S:
	for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes;
	     offset += len) {
	  VGLSetSegment(offset);
	  len = min(VGLBufSize/VGLModeInfo.vi_planes - offset,
		    VGLAdpInfo.va_window_size);
	  for (i = 0; i < VGLModeInfo.vi_planes; i++) {
	    outb(0x3ce, 0x04);
	    outb(0x3cf, i);
	    bcopy(VGLMem, &VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset],
		  len);
	  }
	}
	break;
      case VIDBUF4:
      case VIDBUF8X:
	/*
	 * NOTE: the saved buffer is NOT in the MEMBUF format which 
	 * the ordinary memory bitmap object is stored in. XXX
	 */
	for (i = 0; i < VGLModeInfo.vi_planes; i++) {
	  outb(0x3ce, 0x04);
	  outb(0x3cf, i);
	  bcopy(VGLMem, &VGLBuf[i*VGLAdpInfo.va_window_size],
		VGLAdpInfo.va_window_size);
	}
	break;
      case VIDBUF8:
      case VIDBUF8S:
	for (offset = 0; offset < VGLBufSize; offset += len) {
	  VGLSetSegment(offset);
	  len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size);
          bcopy(VGLMem, &VGLBuf[offset], len);
	}
	break;
      }
      VGLMem = MAP_FAILED;
      munmap(VGLDisplay->Bitmap, VGLAdpInfo.va_window_size);
      ioctl(0, VGLOldMode, 0);
      ioctl(0, KDSETMODE, KD_TEXT);
      ioctl(0, KDDISABIO, 0);
      ioctl(0, VT_RELDISP, VT_TRUE);
      VGLDisplay->Bitmap = VGLBuf;
      VGLDisplay->Type = MEMBUF;
      VGLDisplay->Xsize = VGLDisplay->VXsize;
      VGLDisplay->Ysize = VGLDisplay->VYsize;
      while (!VGLOnDisplay) pause();
    }
  }
}