diff options
Diffstat (limited to 'drivers.c')
-rw-r--r-- | drivers.c | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/drivers.c b/drivers.c new file mode 100644 index 0000000..8679b99 --- /dev/null +++ b/drivers.c @@ -0,0 +1,305 @@ +/* drivers.c + * (c) 2002 Mikulas Patocka + * This file is a part of the Links program, released under GPL + */ + +#include "cfg.h" + +#ifdef G + +#include "links.h" + +int F = 0; + +struct graphics_driver *drv = NULL; + +#ifdef GRDRV_X +extern struct graphics_driver x_driver; +#endif +#ifdef GRDRV_SVGALIB +extern struct graphics_driver svga_driver; +#endif +#ifdef GRDRV_FB +extern struct graphics_driver fb_driver; +#endif +#ifdef GRDRV_DIRECTFB +extern struct graphics_driver directfb_driver; +#endif +#ifdef GRDRV_PMSHELL +extern struct graphics_driver pmshell_driver; +#endif +#ifdef GRDRV_ATHEOS +extern struct graphics_driver atheos_driver; +#endif +#ifdef GRDRV_SDL +extern struct graphics_driver sdl_driver; +#endif + +/* + * On SPAD you must test first svgalib and then X (because X test is slow). + * On other systems you must test first X and then svgalib (because svgalib + * would work in X too and it's undesirable). + */ + +static struct graphics_driver *graphics_drivers[] = { +#ifdef GRDRV_PMSHELL + &pmshell_driver, +#endif +#ifdef GRDRV_ATHEOS + &atheos_driver, +#endif +#ifndef SPAD +#ifdef GRDRV_X + &x_driver, +#endif +#endif +#ifdef GRDRV_FB + /* use FB before DirectFB because DirectFB has bugs */ + &fb_driver, +#endif +#ifdef GRDRV_DIRECTFB + &directfb_driver, +#endif +#ifdef GRDRV_SVGALIB + &svga_driver, +#endif +#ifdef SPAD +#ifdef GRDRV_X + &x_driver, +#endif +#endif +#ifdef GRDRV_SDL + &sdl_driver, +#endif + NULL +}; + +int dummy_block(struct graphics_device *dev) +{ + return 0; +} + +int dummy_unblock(struct graphics_device *dev) +{ + return 0; +} + +#if 0 +static unsigned char *list_graphics_drivers(void) +{ + unsigned char *d = init_str(); + int l = 0; + struct graphics_driver **gd; + for (gd = graphics_drivers; *gd; gd++) { + if (l) add_to_str(&d, &l, " "); + add_to_str(&d, &l, (*gd)->name); + } + return d; +} +#endif + +/* Driver je jednorazovy argument, kterej se preda grafickymu driveru, nikde se dal + * neuklada. Param se skladuje v default_driver param a uklada se do konfiguraku. Pred + * ukoncenim grafickeho driveru se nastavi default_driver_param podle + * drv->get_driver_param. + */ +static unsigned char *init_graphics_driver(struct graphics_driver *gd, unsigned char *param, unsigned char *display) +{ + unsigned char *r; + unsigned char *p = param; + struct driver_param *dp=get_driver_param(gd->name); + if (!param || !*param) p = dp->param; + gd->codepage=dp->codepage; + gd->shell=mem_calloc(MAX_STR_LEN); + if (dp->shell) safe_strncpy(gd->shell,dp->shell,MAX_STR_LEN); + r = gd->init_driver(p,display); + if (r) mem_free(gd->shell), gd->shell = NULL; + return r; +} + + +void add_graphics_drivers(unsigned char **s, int *l) +{ + struct graphics_driver **gd; + for (gd = graphics_drivers; *gd; gd++) { + if (gd != graphics_drivers) add_to_str(s, l, ", "); + add_to_str(s, l, (*gd)->name); + } +} + +unsigned char *init_graphics(unsigned char *driver, unsigned char *param, unsigned char *display) +{ + unsigned char *s = init_str(); + int l = 0; + struct graphics_driver **gd; +#if defined(GRDRV_PMSHELL) && defined(GRDRV_X) + if (is_xterm()) { + static unsigned char swapped = 0; + if (!swapped) { + for (gd = graphics_drivers; *gd; gd++) { + if (*gd == &pmshell_driver) *gd = &x_driver; + else if (*gd == &x_driver) *gd = &pmshell_driver; + } + swapped = 1; + } + } +#endif + for (gd = graphics_drivers; *gd; gd++) { + if (!driver || !*driver || !strcasecmp((*gd)->name, driver)) { + unsigned char *r; + if ((!driver || !*driver) && (*gd)->flags & GD_NOAUTO) continue; + if (!(r = init_graphics_driver(*gd, param, display))) { + mem_free(s); + drv = *gd; + F = 1; + return NULL; + } + if (!l) { + if (!driver || !*driver) add_to_str(&s, &l, "Could not initialize any graphics driver. Tried the following drivers:\n"); + else add_to_str(&s, &l, "Could not initialize graphics driver "); + } + add_to_str(&s, &l, (*gd)->name); + add_to_str(&s, &l, ":\n"); + add_to_str(&s, &l, r); + mem_free(r); + } + } + if (!l) { + add_to_str(&s, &l, "Unknown graphics driver "); + if (driver) add_to_str(&s, &l, driver); + add_to_str(&s, &l, ".\nThe following graphics drivers are supported:\n"); + add_graphics_drivers(&s, &l); + add_to_str(&s, &l, "\n"); + } + return s; +} + +void shutdown_graphics(void) +{ + if (drv) + { + if (drv->shell) mem_free(drv->shell); + drv->shutdown_driver(); + } +} + +void update_driver_param(void) +{ + if (drv) + { + struct driver_param *dp=get_driver_param(drv->name); + dp->codepage=drv->codepage; + if (dp->param) mem_free(dp->param); + dp->param=stracpy(drv->get_driver_param()); + if (dp->shell) mem_free(dp->shell); + dp->shell=stracpy(drv->shell); + dp->nosave = 0; + } +} + +#if defined(GRDRV_SVGALIB)|defined(GRDRV_FB) + +static struct graphics_driver *virtual_device_driver; +struct graphics_device **virtual_devices; +int n_virtual_devices = 0; +struct graphics_device *current_virtual_device; + +static int virtual_device_timer; + +int init_virtual_devices(struct graphics_driver *drv, int n) +{ + if (n_virtual_devices) { + internal("init_virtual_devices: already initialized"); + return -1; + } + if ((unsigned)n > MAXINT / sizeof(struct graphics_device *)) overalloc(); + virtual_devices = mem_calloc(n * sizeof(struct graphics_device *)); + n_virtual_devices = n; + virtual_device_driver = drv; + virtual_device_timer = -1; + current_virtual_device = NULL; + return 0; +} + +struct graphics_device *init_virtual_device(void) +{ + int i; + for (i = 0; i < n_virtual_devices; i++) if (!virtual_devices[i]) { + struct graphics_device *dev; + dev = mem_calloc(sizeof(struct graphics_device)); + dev->size.x2 = virtual_device_driver->x; + dev->size.y2 = virtual_device_driver->y; + current_virtual_device = virtual_devices[i] = dev; + virtual_device_driver->set_clip_area(dev, &dev->size); + return dev; + } + return NULL; +} + +static void virtual_device_timer_fn(void *p) +{ + virtual_device_timer = -1; + if (current_virtual_device && current_virtual_device->redraw_handler) { + drv->set_clip_area(current_virtual_device, ¤t_virtual_device->size); + current_virtual_device->redraw_handler(current_virtual_device, ¤t_virtual_device->size); + } +} + +void switch_virtual_device(int i) +{ + if (i == VD_NEXT) { + int j; + int t = 0; + for (j = 0; j < n_virtual_devices * 2; j++) + if (virtual_devices[j % n_virtual_devices] == current_virtual_device) t = 1; + else if (virtual_devices[j % n_virtual_devices] && t) { + current_virtual_device = virtual_devices[j % n_virtual_devices]; + goto ok_switch; + } + return; + } + if (i < 0 || i >= n_virtual_devices || !virtual_devices[i]) return; + current_virtual_device = virtual_devices[i]; + ok_switch: + if (virtual_device_timer == -1) + virtual_device_timer = install_timer(0, virtual_device_timer_fn, NULL); +} + +void shutdown_virtual_device(struct graphics_device *dev) +{ + int i; + for (i = 0; i < n_virtual_devices; i++) if (virtual_devices[i] == dev) { + virtual_devices[i] = NULL; + mem_free(dev); + if (current_virtual_device != dev) return; + for (; i < n_virtual_devices; i++) if (virtual_devices[i]) { + switch_virtual_device(i); + return; + } + for (i = 0; i < n_virtual_devices; i++) if (virtual_devices[i]) { + switch_virtual_device(i); + return; + } + current_virtual_device = NULL; + return; + } + mem_free(dev); + /*internal("shutdown_virtual_device: device not initialized");*/ +} + +void shutdown_virtual_devices(void) +{ + int i; + if (!n_virtual_devices) { + internal("shutdown_virtual_devices: already shut down"); + return; + } + for (i = 0; i < n_virtual_devices; i++) if (virtual_devices[i]) internal("shutdown_virtual_devices: virtual device %d is still active", i); + mem_free(virtual_devices); + n_virtual_devices = 0; + if (virtual_device_timer != -1) kill_timer(virtual_device_timer), virtual_device_timer = -1; +} + +#endif + +#endif |