static unsigned char *
directfb_fb_init_driver (unsigned char *param, unsigned char *display)
{
  DFBDisplayLayerConfig  config;
  DFBResult              ret;
  unsigned char          *error;
  unsigned char          *result;

  DirectFBInit (&g_argc, (char ***)(void *)&g_argv);
  if ((ret = DirectFBCreate (&dfb)) != DFB_OK) {
      error = (unsigned char *)DirectFBErrorString(ret);
      goto ret;
    }

  if ((ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer)) != DFB_OK) {
      error = (unsigned char *)DirectFBErrorString(ret);
      goto ret_dfb;
  }

  if ((ret = layer->GetConfiguration (layer, &config)) != DFB_OK) {
      error = (unsigned char *)DirectFBErrorString(ret);
      goto ret_layer;
  }

  pixelformat = config.pixelformat;

  directfb_driver.depth = (((DFB_BYTES_PER_PIXEL (pixelformat) & 0x7)) |
                           ((DFB_COLOR_BITS_PER_PIXEL  (pixelformat) & 0x1F) << 3));

  if (directfb_driver.depth == 4)
	directfb_driver.depth = 196;

  /* endian test */
  if (htons (0x1234) == 0x1234) {
     if ((directfb_driver.depth & 0x7) == 2)
	directfb_driver.depth |= 0x100;
     if ((directfb_driver.depth & 0x7) == 4)
	directfb_driver.depth |= 0x200;
  }

  if (!get_color_fn(directfb_driver.depth)) {
	error = cast_uchar "Unsupported color depth";
	goto ret_layer;
  }

  directfb_driver.x = config.width;
  directfb_driver.y = config.height;

  memset (directfb_hash_table, 0, sizeof (directfb_hash_table));

  if ((ret = dfb->CreateEventBuffer (dfb, &events)) != DFB_OK) {
      error = (unsigned char *)DirectFBErrorString(ret);
      goto ret_layer;
  }

  event_timer = install_timer (20, directfb_check_events, events);

  if (dfb->CreateSurface (dfb, directfb_get_arrow_desc(), &arrow) != DFB_OK)
    arrow = NULL;

  return NULL;

ret_layer:
  layer->Release(layer);
ret_dfb:
  dfb->Release(dfb);
ret:
  result = init_str();
  add_to_strn(&result, error);
  add_to_strn(&result, cast_uchar "\n");
  return result;
}
예제 #2
0
static unsigned char *fb_init_driver(unsigned char *param, unsigned char *ignore)
{
	unsigned char *e;
	struct stat st;
	int rs;
	unsigned long ul;

	TTY = 0;
	EINTRLOOP(rs, ioctl(TTY,VT_GETMODE, &vt_omode));
	if (rs == -1) {
		TTY = 1;
		EINTRLOOP(rs, ioctl(TTY,VT_GETMODE, &vt_omode));
		if (rs == -1) {
			TTY = 0;
		}
	}

	kbd_set_raw = 1;
	fb_old_vd = NULL;
	fb_driver_param=NULL;
	if(param != NULL)
		fb_driver_param=stracpy(param);

	border_left = border_right = border_top = border_bottom = 0;
	if (!param) param=cast_uchar "";
	if (*param) {
		if (*param < '0' || *param > '9') {
			bad_p:
			if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
			return stracpy(cast_uchar "-mode syntax is left_border[,top_border[,right_border[,bottom_border]]]\n");
		}
		ul = strtoul(cast_const_char param, (char **)(void *)&param, 10);
		if (ul > MAXINT / 10) goto bad_p;
		border_left = (int)ul;
		if (*param == ',') param++;
	} else {
		border_left = 0;
	}
	if (*param) {
		if (*param < '0' || *param > '9') goto bad_p;
		ul = strtoul(cast_const_char param, (char **)(void *)&param, 10);
		if (ul > MAXINT / 10) goto bad_p;
		border_top = (int)ul;
		if (*param == ',') param++;
	} else {
		border_top = border_left;
	}
	if (*param) {
		if (*param < '0' || *param > '9') goto bad_p;
		ul = strtoul(cast_const_char param, (char **)(void *)&param, 10);
		if (ul > MAXINT / 10) goto bad_p;
		border_right = (int)ul;
		if (*param == ',') param++;
	} else {
		border_right = border_left;
	}
	if (*param) {
		if (*param < '0' || *param > '9') goto bad_p;
		ul = strtoul(cast_const_char param, (char **)(void *)&param, 10);
		if (ul > MAXINT / 10) goto bad_p;
		border_bottom = (int)ul;
		if (*param == ',') param++;
	} else {
		border_bottom = border_top;
	}
	if (*param) goto bad_p;

	EINTRLOOP(rs, fstat(TTY, &st));
	if (rs) {
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		return stracpy(cast_uchar "Cannon stat stdin.\n");
	}

	fb_console = (int)(st.st_rdev & 0xff);

	fb_hide_cursor();

	if ((e = fb_switch_init())) {
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return e;
	}

	EINTRLOOP(fb_handle, open("/dev/fb0", O_RDWR));
	if (fb_handle==-1) {
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Cannot open /dev/fb0.\n");
	}

	EINTRLOOP(rs, ioctl(fb_handle, FBIOGET_VSCREENINFO, &vi));
	if (rs==-1)
	{
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Cannot get FB VSCREENINFO.\n");
	}

	/*oldmode=vi;*/

	EINTRLOOP(rs, ioctl(fb_handle, FBIOGET_FSCREENINFO, &fi));
	if (rs==-1)
	{
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Cannot get FB FSCREENINFO.\n");
	}

	fb_xsize=vi.xres;
	fb_ysize=vi.yres;
	fb_bits_pp=vi.bits_per_pixel;
	if (fb_bits_pp == 16 && vi.green.length == 5) fb_bits_pp = 15;

	if (fb_xsize <= border_left + border_right) border_left = border_right = 0;
	fb_xsize -= border_left + border_right;
	if (fb_ysize <= border_top + border_bottom) border_top = border_bottom = 0;
	fb_ysize -= border_top + border_bottom;

	fb_driver.x=fb_xsize;
	fb_driver.y=fb_ysize;

	switch(fb_bits_pp)
	{
		case 4:
		fb_pixelsize=1;
		fb_palette_colors=16;
		break;

		case 8:
		fb_pixelsize=1;
		fb_palette_colors=256;
		break;

		case 15:
		case 16:
		fb_pixelsize=2;
		fb_palette_colors=64;
		break;

		case 24:
		fb_palette_colors=256;
		fb_pixelsize=3;
		break;

		case 32:
		fb_palette_colors=256;
		fb_pixelsize=4;
		fb_bits_pp=24;
		break;

		default:
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Unknown bit depth");
	}
	fb_colors=1<<fb_bits_pp;

	/* we must pan before setting palette */
	fb_pan_display();

	have_cmap = 0;
	if (fi.visual==FB_VISUAL_PSEUDOCOLOR && fb_colors <= 0x1000000) /* set palette */
	{
		have_cmap=1;
		fb_palette_colors=fb_colors;
		alloc_palette(&old_palette);
		get_palette(&old_palette);

		alloc_palette(&global_pal);
		generate_palette(&global_pal);
		set_palette(&global_pal);
	}
	if (fi.visual==FB_VISUAL_DIRECTCOLOR) /* set pseudo palette */
	{
		have_cmap=2;
		alloc_palette(&old_palette);
		get_palette(&old_palette);

		alloc_palette(&global_pal);
		generate_palette(&global_pal);
		set_palette(&global_pal);
	}

	fb_linesize=fi.line_length;
	fb_mem_size=fi.smem_len;

	if (init_virtual_devices(&fb_driver, NUMBER_OF_DEVICES)){
		fb_shutdown_palette();
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Allocation of virtual devices failed.\n");
	}
	fb_kbd = handle_svgalib_keyboard(fb_key_in);

	/* Mikulas: nechodi to na sparcu */
	if (fb_mem_size < (unsigned)((border_top + fb_ysize + border_bottom) * fb_linesize))
	{
		fb_shutdown_palette();
		svgalib_free_trm(fb_kbd);
		shutdown_virtual_devices();
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Nonlinear mapping of graphics memory not supported.\n");
	}

	if (vi.nonstd) {
		fb_shutdown_palette();
		svgalib_free_trm(fb_kbd);
		shutdown_virtual_devices();
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Non-standard pixel format.\n");
	}

	fb_driver.flags |= GD_DONT_USE_SCROLL;
#ifdef USE_FB_ACCEL
	need_accel_sync = 0;
	EINTRLOOP(rs, ioctl(fb_handle, FBIO_ACCEL_SUPPORT));
	if (rs < 0) {
		accel_flags = 0;
		/*debug("accel not supported");*/
	} else {
		accel_flags = rs;
		/*debug("accel supported, flags %x", accel_flags);*/
	}
	if (fb_bits_pp != 8)
		accel_flags &= ~(FB_ACCEL_FILLRECT_SUPPORTED | FB_ACCEL_FILLRECT_ACCELERATED);
	if (accel_flags & FB_ACCEL_COPYAREA_ACCELERATED)
		fb_driver.flags &= ~GD_DONT_USE_SCROLL;
#endif

	/*
	 * Some framebuffer implementations (for example Mach64) on Sparc64 hate
	 * partial framebuffer mappings.
	 *
	 * For others, we can save virtual memory space by doing a partial mmap.
	 */
	fb_mapped_size = (border_top + fb_ysize + border_bottom) * fb_linesize;
retry1:
	if ((fb_mem=mmap(0,fb_mapped_size,PROT_READ|PROT_WRITE,MAP_SHARED,fb_handle,0))==MAP_FAILED) {
		if (errno == EINTR) goto retry1;
		fb_mapped_size = fb_mem_size;
retry2:
		if ((fb_mem=mmap(0,fb_mapped_size,PROT_READ|PROT_WRITE,MAP_SHARED,fb_handle,0))==MAP_FAILED) {
			if (errno == EINTR) goto retry2;
			fb_shutdown_palette();
			svgalib_free_trm(fb_kbd);
			shutdown_virtual_devices();

			EINTRLOOP(rs, close(fb_handle));
			fb_switch_shutdown();
			if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
			fb_show_cursor();
			return stracpy(cast_uchar "Cannot mmap graphics memory.\n");
		}
	}
	fb_vmem = fb_mem + border_left * fb_pixelsize + border_top * fb_linesize;
	fb_driver.depth=fb_pixelsize&7;
	fb_driver.depth|=(fb_bits_pp&31)<<3;
	if (htonl(0x12345678) == 0x12345678) {
		/* Big endian */
		if (fb_driver.depth == 130 || fb_driver.depth == 122) fb_driver.depth |= 1 << 8;
		else if (fb_driver.depth == 196) fb_driver.depth |= 1 << 9;
	}

	fb_driver.get_color=get_color_fn(fb_driver.depth);
	if (!fb_driver.get_color) {
		fb_shutdown_palette();
		svgalib_free_trm(fb_kbd);
		shutdown_virtual_devices();

		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Unknown bit format.\n");
	}
	install_signal_handler(SIGINT, (void (*)(void *))fb_ctrl_c, fb_kbd, 0);

	/* mouse */
	mouse_buffer=mem_alloc(fb_pixelsize*arrow_area);
	background_buffer=mem_alloc(fb_pixelsize*arrow_area);
	new_background_buffer=mem_alloc(fb_pixelsize*arrow_area);
	background_x=mouse_x=fb_xsize>>1;
	background_y=mouse_y=fb_ysize>>1;
	mouse_black=fb_driver.get_color(0);
	mouse_white=fb_driver.get_color(0xffffff);
	mouse_graphics_device=fb_driver.init_device();
	virtual_devices[0] = NULL;
	global_mouse_hidden=1;
	last_mouse_buttons = B_MOVE;
	if (handle_fb_mouse()) {
		fb_driver.shutdown_device(mouse_graphics_device);
		mem_free(mouse_buffer);
		mem_free(background_buffer);
		mem_free(new_background_buffer);
		fb_shutdown_palette();
		svgalib_free_trm(fb_kbd);
		shutdown_virtual_devices();

		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Cannot open GPM mouse.\n");
	}
	/* hide cursor */
	if (border_left | border_top | border_right | border_bottom) fb_clear_videoram();

	show_mouse();

	END_GR

	return NULL;
}