[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH v2] + cdi.video: vesa
Achtung, qemu-spezifisch! Funktioniert so in anderen Umgebungen nicht.
Signed-off-by: Alexander Siol <alex@xxxxxxxxxx>
---
src/modules/cdi/vesa/Makefile.all | 6 +
src/modules/cdi/vesa/bitmap.c | 77 ++++++++
src/modules/cdi/vesa/bitmap.h | 13 ++
src/modules/cdi/vesa/device.c | 185 ++++++++++++++++++++
src/modules/cdi/vesa/device.h | 15 ++
src/modules/cdi/vesa/drawing.c | 345 +++++++++++++++++++++++++++++++++++++
src/modules/cdi/vesa/drawing.h | 59 +++++++
src/modules/cdi/vesa/main.c | 124 +++++++++++++
src/modules/cdi/vesa/vesa.h | 47 +++++
9 files changed, 871 insertions(+), 0 deletions(-)
create mode 100644 src/modules/cdi/vesa/Makefile.all
create mode 100644 src/modules/cdi/vesa/bitmap.c
create mode 100644 src/modules/cdi/vesa/bitmap.h
create mode 100644 src/modules/cdi/vesa/device.c
create mode 100644 src/modules/cdi/vesa/device.h
create mode 100644 src/modules/cdi/vesa/drawing.c
create mode 100644 src/modules/cdi/vesa/drawing.h
create mode 100644 src/modules/cdi/vesa/main.c
create mode 100644 src/modules/cdi/vesa/vesa.h
diff --git a/src/modules/cdi/vesa/Makefile.all b/src/modules/cdi/vesa/Makefile.all
new file mode 100644
index 0000000..ec6f85a
--- /dev/null
+++ b/src/modules/cdi/vesa/Makefile.all
@@ -0,0 +1,6 @@
+shopt -s extglob
+source $LOST_BUILDMK_ROOT/config.sh
+
+echo "LD $1/modules/vesa"
+$LOST_TOOLS_LD -ovesa.mod -Ttext=0x40000000 *.o --start-group $2 --end-group
+$LOST_TOOLS_STRIP -s vesa.mod -o $1/modules/vesa
diff --git a/src/modules/cdi/vesa/bitmap.c b/src/modules/cdi/vesa/bitmap.c
new file mode 100644
index 0000000..1609c70
--- /dev/null
+++ b/src/modules/cdi/vesa/bitmap.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander Siol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#include <cdi/video.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+struct cdi_video_bitmap* vesa_bitmap_create(struct cdi_video_device* device,
+ unsigned int width, unsigned int height, void* data)
+{
+ struct cdi_video_bitmap* bitmap = calloc(1,sizeof(struct cdi_video_bitmap));
+
+ bitmap->device = device;
+ bitmap->width = width;
+ bitmap->height = height;
+ bitmap->format.bpp = 32;
+ bitmap->format.red_bits = 8;
+ bitmap->format.red_offset = 16;
+ bitmap->format.green_bits = 8;
+ bitmap->format.green_offset = 8;
+ bitmap->format.blue_bits = 8;
+ bitmap->format.blue_offset = 0;
+
+ bitmap->pitch = bitmap->format.bpp / 8 * width;
+
+ bitmap->in_vram = 0;
+
+ bitmap->pixeldata = calloc(1, width * height * 4);
+ if (data) {
+ memcpy(bitmap->pixeldata, data, width * height * 4);
+ }
+
+ return bitmap;
+}
+
+void vesa_bitmap_destroy(struct cdi_video_bitmap* bitmap)
+{
+ if (bitmap->in_vram == 0) {
+ free(bitmap->pixeldata);
+ }
+ free(bitmap);
+}
+
+void vesa_bitmap_set_usage_hint(struct cdi_video_device* device,
+ struct cdi_video_bitmap* bitmap, enum cdi_video_bitmap_usage_hint hint)
+{
+ /*
+ Meiner Meinung nach kann sowas mit VESA garnicht gescheit gemacht werden -
+ immerhin sind eh alle Bitmaps im genau gleichen RAM.
+ */
+ return;
+}
\ No newline at end of file
diff --git a/src/modules/cdi/vesa/bitmap.h b/src/modules/cdi/vesa/bitmap.h
new file mode 100644
index 0000000..636b700
--- /dev/null
+++ b/src/modules/cdi/vesa/bitmap.h
@@ -0,0 +1,13 @@
+
+#ifndef __VESA_BITMAP_H__
+#define __VESA_BITMAP_H__
+
+#include <cdi/video.h>
+
+void vesa_bitmap_set_usage_hint(struct cdi_video_device *device,
+ struct cdi_video_bitmap *bitmap, enum cdi_video_bitmap_usage_hint hint);
+void vesa_bitmap_destroy(struct cdi_video_bitmap *bitmap);
+struct cdi_video_bitmap *vesa_bitmap_create(struct cdi_video_device *device,
+ unsigned int width, unsigned int height, void *data);
+
+#endif /* __VESA_BITMAP_H__ */
diff --git a/src/modules/cdi/vesa/device.c b/src/modules/cdi/vesa/device.c
new file mode 100644
index 0000000..df9a438
--- /dev/null
+++ b/src/modules/cdi/vesa/device.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander Siol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#include "device.h"
+#include <cdi/video.h>
+#include <cdi/vesa.h>
+#include <cdi/lists.h>
+#include <cdi/pci.h>
+#include <cdi/misc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "vesa.h"
+#include "drawing.h"
+#include "bitmap.h"
+
+struct vesa_device* vesa_device_create(char* name, struct cdi_pci_device* pci)
+{
+ // Device anlegen
+ struct vesa_device* dev;
+ dev = malloc(sizeof(struct vesa_device));
+ dev->dev.dev.name = name;
+ dev->dev.displays = cdi_list_create();
+
+ dev->dev.raster_op = CDI_VIDEO_ROP_COPY;
+ dev->dev.restore_data = NULL;
+
+ dev->dev.vram = NULL;
+ dev->dev.vram_size = 0;
+
+ int i;
+
+ // Ressourcen holen (Speicher als Framebuffer)
+ // FIXME: Hack, Keine Ahnung ob das auÃ?erhalb von qemu tut.
+ cdi_pci_alloc_memory(pci);
+ for (i = 0; i < cdi_list_size(pci->resources); i++) {
+ struct cdi_pci_resource* res;
+ res = cdi_list_get(pci->resources, i);
+ if (res->type == CDI_PCI_MEMORY && res->length > 0x1000) {
+ dev->dev.vram = res->address;
+ dev->dev.vram_size = res->length;
+ break;
+ }
+ }
+
+ // Display anlegen
+ struct cdi_video_display* vesadisplay;
+ vesadisplay = calloc(1,sizeof(struct cdi_video_display));
+
+ vesadisplay->device = (struct cdi_video_device*)dev;
+ vesadisplay->mode = NULL;
+ vesadisplay->modes = cdi_list_create();
+
+ // Muss bei change_mode sinnvoll gesetzt werden
+ vesadisplay->frontbuffer = NULL;
+
+ cdi_list_push(dev->dev.displays, vesadisplay);
+
+ return dev;
+}
+
+/**
+ * Callback fuer CDI-Vesa-Modi
+ */
+void vesa_mode_callback(int modenum, struct cdi_video_vesa_mode_info *modeinfo)
+{
+ switch (modeinfo->depth) {
+ case 32:
+ case 24:
+ case 16:
+ printf("Modus OK: %dx%d\n", modeinfo->width, modeinfo->height);
+ struct cdi_video_display *vesadisplay;
+ struct vesa_device *vesadev;
+ // Geraet & Display suchen.
+ // VESA kann nur ein Geraet und ein Display
+ vesadev = cdi_list_get(vesa_driver.drv.drv.devices, 0);
+ vesadisplay = cdi_list_get(vesadev->dev.displays, 0);
+
+ // Modus hinzufuegen
+ struct cdi_video_vesa_mode *vesamode;
+ vesamode = calloc(1,sizeof(struct cdi_video_vesa_mode));
+ vesamode->vesamode = modenum;
+ vesamode->mode.width = modeinfo->width;
+ vesamode->mode.height = modeinfo->height;
+ vesamode->mode.depth = modeinfo->depth;
+ cdi_list_push(vesadisplay->modes, vesamode);
+
+ break;
+ default:
+ /*
+ Andere Modi sind einfach zu ungenau um die wirklich in Erwaegung zu
+ ziehen, auch wenn die technisch moeglich waeren
+ */
+ break;
+ }
+ return;
+}
+
+/**
+ * Modus setzen
+ */
+int vesa_display_set_mode(struct cdi_video_device* device,
+ struct cdi_video_display* display, struct cdi_video_displaymode* mode)
+{
+ struct cdi_video_vesa_mode* vesamode;
+ vesamode = (struct cdi_video_vesa_mode*)mode;
+ cdi_video_vesa_change_mode(vesamode->vesamode);
+
+ struct cdi_video_bitmap* bitmap;
+ if (display->frontbuffer != NULL) {
+ bitmap = display->frontbuffer;
+ } else {
+ bitmap = calloc(1, sizeof(struct cdi_video_bitmap));
+ }
+
+ struct cdi_video_vesa_mode_info* vesamodeinfo;
+ vesamodeinfo = cdi_video_vesa_get_mode(vesamode->vesamode);
+
+ bitmap->width = mode->width;
+ bitmap->height = mode->height;
+ bitmap->format.bpp = vesamodeinfo->depth;
+ bitmap->format.red_bits = vesamodeinfo->redmasksize;
+ bitmap->format.red_offset = vesamodeinfo->redfieldpos;
+ bitmap->format.green_bits = vesamodeinfo->greenmasksize;
+ bitmap->format.green_offset = vesamodeinfo->greenfieldpos;
+ bitmap->format.blue_bits = vesamodeinfo->bluemasksize;
+ bitmap->format.blue_offset = vesamodeinfo->bluefieldpos;
+ bitmap->format.alpha_bits = 0;
+ bitmap->format.alpha_offset = 0;
+
+ // Offsets muessen auf 32-bit passen.
+ if (bitmap->format.bpp == 16) {
+ bitmap->format.red_offset += 16;
+ bitmap->format.green_offset += 16;
+ bitmap->format.blue_offset += 16;
+ }
+
+ bitmap->in_vram = 1;
+ bitmap->device = device;
+ bitmap->pixeldata = NULL; // Im VRAM, passt so
+ bitmap->pitch = bitmap->width * bitmap->format.bpp / 8;
+
+ display->frontbuffer = bitmap;
+
+#if 0
+ // Die Sichere Variante um das Bitmap zu schwaerzen
+ struct cdi_video_color color;
+ color.alpha = 0;
+ color.red = 0;
+ color.green = 0;
+ color.blue = 0;
+
+ vesa_draw_rectangle(bitmap, 0, 0, bitmap->width, bitmap->height, &color);
+#endif
+
+ // Inkorrekte Variante, aber schneller - und macht effektiv das gleiche.
+ memset(bitmap->device->vram, 0, bitmap->width * bitmap->height *
+ bitmap->format.bpp);
+
+ return 0;
+}
diff --git a/src/modules/cdi/vesa/device.h b/src/modules/cdi/vesa/device.h
new file mode 100644
index 0000000..7f5ea22
--- /dev/null
+++ b/src/modules/cdi/vesa/device.h
@@ -0,0 +1,15 @@
+
+#ifndef __VESA_DEVICE_H__
+#define __VESA_DEVICE_H__
+
+#include <cdi/pci.h>
+#include <cdi/vesa.h>
+#include <cdi/video.h>
+
+void vesa_mode_callback(int modenum,
+ struct cdi_video_vesa_mode_info *modeinfo);
+struct vesa_device *vesa_device_create(char *name, struct cdi_pci_device* pci);
+int vesa_display_set_mode(struct cdi_video_device *device,
+ struct cdi_video_display *display, struct cdi_video_displaymode *mode);
+
+#endif /* __VESA_DEVICE_H__ */
diff --git a/src/modules/cdi/vesa/drawing.c b/src/modules/cdi/vesa/drawing.c
new file mode 100644
index 0000000..480dbd1
--- /dev/null
+++ b/src/modules/cdi/vesa/drawing.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander Siol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#include <cdi/video.h>
+#include <stdio.h>
+#include "drawing.h"
+#include <stdlib.h>
+
+
+#define min(x,y) (((x) < (y)) ? (x) : (y))
+
+uint32_t colormasks[3] = { 0xffff0000, 0x00ffffff, 0xffffffff }; // 16, 24, 32 bpp
+
+void vesa_set_raster_op(struct cdi_video_device* device,
+ enum cdi_video_raster_op rop)
+{
+ device->raster_op = rop;
+}
+
+void vesa_draw_line(struct cdi_video_bitmap* target, unsigned int x1,
+ unsigned int y1, unsigned int x2, unsigned int y2,
+ struct cdi_video_color* color)
+{
+ // Speicher suchen
+ char *dstchar = NULL;
+ if (target->in_vram == 1) {
+ dstchar = target->device->vram;
+ }
+ int x_shift = target->format.bpp / 8;
+
+ dstchar += (uint32_t)target->pixeldata;
+ dstchar += y1 * target->pitch;
+ dstchar += x1 * x_shift;
+
+ // Farben und Farbmasken
+ uint32_t new = 0, old = 0;
+ uint32_t colormask, keepmask;
+
+ colormask = colormasks[(target->format.bpp - 16) / 8];
+ keepmask = ~colormask;
+
+ new = convert_color(target->format, color);
+
+ // Bresenham Initialisierung
+ int dx = x2 - x1;
+ int dy = y2 - y1;
+
+ int xstep = 0, ystep = 0;
+ int normal_step_x, normal_step_y, error_fast, error_slow;
+ int error, i;
+
+ if (dx > 0) {
+ xstep = x_shift;
+ } else if (dx < 0) {
+ xstep = -x_shift;
+ dx = -dx;
+ }
+
+ if (dy > 0) {
+ ystep = target->pitch;
+ } else if (dy < 0) {
+ ystep = -target->pitch;
+ dy = -dy;
+ }
+
+ if (dx > dy) {
+ normal_step_x = xstep;
+ normal_step_y = 0;
+ error_fast = dy;
+ error_slow = dx;
+ } else {
+ normal_step_x = 0;
+ normal_step_y = ystep;
+ error_fast = dx;
+ error_slow = dy;
+ }
+ error = error_slow >> 1;
+
+
+ for (i = 0; i <= error_slow; i++) {
+ old = *(uint32_t*)dstchar & colormask;
+ *(uint32_t*)dstchar &= keepmask;
+ *(uint32_t*)dstchar |= new & colormask;
+
+ error -= error_fast;
+ if (error < 0) {
+ error += error_slow;
+ dstchar += xstep;
+ dstchar += ystep;
+ } else {
+ dstchar += normal_step_x;
+ dstchar += normal_step_y;
+ }
+ }
+}
+
+void vesa_draw_rectangle(struct cdi_video_bitmap* target, unsigned int x,
+ unsigned int y, unsigned int width, unsigned int height,
+ struct cdi_video_color* color)
+{
+ int widthctr;
+ // Pixel vorbereiten
+ char* linestart = NULL;
+ char* in_line;
+ if (target->in_vram == 1) {
+ linestart = target->device->vram;
+ }
+ int x_shift = target->format.bpp / 8;
+
+ linestart += (uint32_t)target->pixeldata;
+ linestart += y * target->pitch;
+ linestart += x * x_shift;
+
+ // Farben und Farbmasken
+ uint32_t new = 0, old = 0;
+ uint32_t colormask, keepmask;
+
+ colormask = colormasks[(target->format.bpp - 16) / 8];
+ keepmask = ~colormask;
+
+ new = convert_color(target->format, color);
+
+ while (height > 0) {
+ // Render Line
+ widthctr = width;
+ in_line = linestart;
+ while (widthctr > 0) {
+ // Render Pixel
+ old = *(uint32_t*)in_line & colormask;
+ new = do_rop(target->device->raster_op, new, old);
+
+ *(uint32_t*)in_line &= keepmask;
+ *(uint32_t*)in_line |= new & colormask;
+
+ in_line += x_shift;
+ widthctr--;
+ }
+ // Eine Reihe weiter
+ height--;
+ linestart += target->pitch;
+ }
+}
+
+// TODO TODO TODO TODO TODO
+void vesa_draw_ellipse(struct cdi_video_bitmap* target, unsigned int x,
+ unsigned int y, unsigned int width, unsigned int height,
+ struct cdi_video_color* color);
+
+void vesa_draw_bitmap(struct cdi_video_bitmap* target,
+ struct cdi_video_bitmap* source, unsigned int x, unsigned int y)
+{
+ vesa_draw_bitmap_part(target, source, x, y, 0, 0, source->width,
+ source->height);
+}
+
+void vesa_draw_bitmap_part(struct cdi_video_bitmap* target,
+ struct cdi_video_bitmap* source, unsigned int x, unsigned int y,
+ unsigned int srcx, unsigned int srcy, unsigned int width,
+ unsigned int height)
+{
+ int copywidth, copyheight, origcopywidth;
+
+ // Zu kopierenden Bereich festlegen
+ copywidth = min( min( target->width - x, width ),
+ source->width - srcx);
+ copyheight = min (min (target->height - y, height),
+ source->height - srcy);
+
+ // Speicherstellen berechnen
+ char* srcchar = NULL;
+ if (source->in_vram == 1) { srcchar = source->device->vram; }
+ srcchar += (int)source->pixeldata;
+ srcchar += (int)(srcx * source->format.bpp / 8);
+ srcchar += (int)(srcy * source->pitch);
+
+ char* dstchar = NULL;
+ if (target->in_vram == 1) { dstchar = target->device->vram; }
+ dstchar += (int)target->pixeldata;
+ dstchar += (int)(x * target->format.bpp / 8);
+ dstchar += (int)(y * target->pitch);
+
+ char *dstline, *srcline;
+
+ // Farben und Farbmasken
+ uint32_t new = 0, old = 0;
+ struct cdi_video_color* newcolor;
+ uint32_t colormask, keepmask;
+
+ colormask = colormasks[(target->format.bpp - 16) / 8];
+ keepmask = ~colormask;
+
+ // Schleifenvorbereitung
+ dstline = dstchar;
+ srcline = srcchar;
+ origcopywidth = copywidth;
+ while (copyheight > 0) {
+ copywidth = origcopywidth;
+ while (copywidth > 0) {
+ // Farben vorbereiten
+ old = *(uint32_t*)dstchar & colormask;
+ newcolor = convert_color_from_pixel(source->format,
+ *(uint32_t*)srcchar);
+ new = convert_color(target->format, newcolor);
+ new = do_rop(target->device->raster_op, new, old);
+ free(newcolor);
+
+ // Malen
+ *(uint32_t*)dstchar &= keepmask;
+ *(uint32_t*)dstchar |= new & colormask;
+
+ // Zeiger einen Pixel weitersetzen
+ srcchar += source->format.bpp / 8;
+ dstchar += target->format.bpp / 8;
+ copywidth--;
+ }
+ // Linie fertig, naechste benutzen.
+ dstline += target->pitch;
+ srcline += source->pitch;
+ srcchar = srcline;
+ dstchar = dstline;
+ copyheight--;
+ }
+}
+
+inline void vesa_draw_dot(struct cdi_video_bitmap* target, unsigned int x,
+ unsigned int y, struct cdi_video_color* color)
+{
+ // Speicherposition berechnen
+ char *tmp;
+ if (target->in_vram == 1) {
+ tmp = target->device->vram;
+ } else {
+ tmp = NULL;
+ }
+ tmp += (int)(target->pixeldata);
+ tmp += (int)(y * (target->pitch));
+ tmp += (int)(x * (target->format.bpp) / 8);
+
+ uint32_t *start = (uint32_t*)tmp;
+
+ // Farben und Farbmasken definieren.
+ uint32_t newcolor = 0, oldcolor = 0;
+ uint32_t colormask, keepmask;
+ colormask = colormasks[(target->format.bpp - 16) / 8];
+ keepmask = ~colormask;
+
+ // Farbe berechnen
+ oldcolor = *start & colormask;
+ newcolor = convert_color(target->format, color);
+ newcolor = do_rop(target->device->raster_op, newcolor, oldcolor);
+
+ // und setzen.
+ *start &= keepmask;
+ *start |= newcolor & colormask;
+}
+
+inline uint32_t do_rop(enum cdi_video_raster_op rop, uint32_t new, uint32_t old)
+{
+ switch (rop) {
+ case CDI_VIDEO_ROP_OR:
+ return new | old;
+ case CDI_VIDEO_ROP_XOR:
+ return new ^ old;
+ case CDI_VIDEO_ROP_AND:
+ return new & old;
+ default:
+ fprintf(0, "VESA unterstützt ROP %d nicht\n",
+ rop);
+ // Hier _kein_ break, damit im Fehlerfall wenigstens was rauskommt.
+ case CDI_VIDEO_ROP_COPY:
+ return new;
+ }
+}
+
+inline uint32_t convert_color(struct cdi_video_pixel_format fmt,
+ struct cdi_video_color* cdicolor)
+{
+ uint32_t red, blue, green, alpha, color;
+ red = cdicolor->red << fmt.red_bits >> 8;
+ green = cdicolor->green << fmt.green_bits >> 8;
+ blue = cdicolor->blue << fmt.blue_bits >> 8;
+
+ // Hier pruefen reicht, RGB sollte eigentlich immer da sein.
+ if (fmt.alpha_bits > 0) {
+ alpha = cdicolor->alpha << fmt.alpha_bits >> 8;
+ } else {
+ alpha = 0;
+ }
+ color = red << fmt.red_offset |
+ green << fmt.green_offset |
+ blue << fmt.blue_offset |
+ alpha << fmt.alpha_offset;
+ return color;
+}
+
+struct cdi_video_color* convert_color_from_pixel(struct cdi_video_pixel_format
+ fmt, uint32_t value)
+{
+ struct cdi_video_color* color = malloc(sizeof(struct cdi_video_color));
+ int redmask, bluemask, greenmask, alphamask;
+
+ // Masken setzen
+ redmask = ((1 << fmt.red_bits) - 1) << fmt.red_offset;
+ greenmask = ((1 << fmt.green_bits) - 1) << fmt.green_offset;
+ bluemask = ((1 << fmt.blue_bits) - 1) << fmt.blue_offset;
+ alphamask = ((1 << fmt.alpha_bits) - 1) << fmt.alpha_offset;
+
+ // Farben extrahieren
+ color->red = (value & redmask) >> fmt.red_offset;
+ color->green = (value & greenmask) >> fmt.green_offset;
+ color->blue = (value & bluemask) >> fmt.blue_offset;
+ color->alpha = (value & alphamask) >> fmt.alpha_offset;
+
+ // Auf die richtige Aufloesung bringen.
+ color->red = color->red << 8 >> fmt.red_bits;
+ color->green = color->green << 8 >> fmt.green_bits;
+ color->blue = color->blue << 8 >> fmt.blue_bits;
+ color->alpha = color->alpha << 8 >> fmt.alpha_bits;
+
+ return color;
+}
diff --git a/src/modules/cdi/vesa/drawing.h b/src/modules/cdi/vesa/drawing.h
new file mode 100644
index 0000000..2232cfe
--- /dev/null
+++ b/src/modules/cdi/vesa/drawing.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander Siol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#ifndef __VESA_DRAWING_H__
+#define __VESA_DRAWING_H__
+
+#include <cdi/video.h>
+
+void vesa_set_raster_op(struct cdi_video_device* device,
+ enum cdi_video_raster_op rop);
+void vesa_draw_line(struct cdi_video_bitmap* target, unsigned int x1,
+ unsigned int y1, unsigned int x2, unsigned int y2,
+ struct cdi_video_color* color);
+void vesa_draw_rectangle(struct cdi_video_bitmap* target, unsigned int x,
+ unsigned int y, unsigned int width, unsigned int height,
+ struct cdi_video_color* color);
+void vesa_draw_ellipse(struct cdi_video_bitmap* target, unsigned int x,
+ unsigned int y, unsigned int width, unsigned int height,
+ struct cdi_video_color* color);
+void vesa_draw_bitmap(struct cdi_video_bitmap* target,
+ struct cdi_video_bitmap* bitmap, unsigned int x, unsigned int y);
+void vesa_draw_bitmap_part(struct cdi_video_bitmap* target,
+ struct cdi_video_bitmap* bitmap, unsigned int x, unsigned int y,
+ unsigned int srcx, unsigned int srcy, unsigned int width,
+ unsigned int height);
+inline void vesa_draw_dot(struct cdi_video_bitmap* target, unsigned int x,
+ unsigned int y, struct cdi_video_color* color);
+
+inline uint32_t do_rop(enum cdi_video_raster_op rop, uint32_t new, uint32_t old);
+inline uint32_t convert_color(struct cdi_video_pixel_format fmt,
+ struct cdi_video_color* cdicolor);
+struct cdi_video_color* convert_color_from_pixel(struct cdi_video_pixel_format
+ fmt, uint32_t value);
+
+#endif /* __VESA_DRAWING_H__ */
diff --git a/src/modules/cdi/vesa/main.c b/src/modules/cdi/vesa/main.c
new file mode 100644
index 0000000..416138f
--- /dev/null
+++ b/src/modules/cdi/vesa/main.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2008 Alexander Siol
+ *
+ * This program is free software. It comes without any warranty, to
+ * the extent permitted by applicable law. You can redistribute it
+ * and/or modify it under the terms of the Do What The Fuck You Want
+ * To Public License, Version 2, as published by Sam Hocevar. See
+ * http://sam.zoy.org/projects/COPYING.WTFPL for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cdi.h>
+#include <cdi/misc.h>
+#include <cdi/video.h>
+#include <cdi/pci.h>
+#include <cdi/lists.h>
+#include <cdi/vesa.h>
+
+#include "vesa.h"
+#include "bitmap.h"
+#include "device.h"
+#include "drawing.h"
+
+char* driver_name = "vesa";
+struct cdi_video_vesa_driver vesa_driver;
+
+static void vesa_driver_init(void);
+static void vesa_driver_destroy(struct cdi_driver* driver);
+void vesa_init_device(struct cdi_device* device);
+
+#define DEBUG printf
+#define TODO //
+
+#ifdef CDI_STANDALONE
+int main(void)
+#else
+int init_vesa(void)
+#endif
+{
+ DEBUG("vesa driver running\n");
+ cdi_init();
+ vesa_driver_init();
+
+ cdi_run_drivers();
+
+ return 0;
+}
+
+/**
+ * Initialisiert den Treiber und registriert ihn
+ */
+static void vesa_driver_init(void)
+{
+ cdi_list_t pci_devices;
+ struct cdi_pci_device* pci;
+
+ memset(&vesa_driver, 0, sizeof(vesa_driver));
+ cdi_video_driver_init((struct cdi_video_driver*)&vesa_driver);
+
+ // Fill driver struct
+ vesa_driver.drv.drv.name = driver_name;
+ vesa_driver.drv.drv.type = CDI_VIDEO;
+ vesa_driver.drv.drv.init_device = NULL;//vesa_init_device;
+ vesa_driver.drv.drv.remove_device = NULL;
+ vesa_driver.drv.drv.destroy = vesa_driver_destroy;
+
+ vesa_driver.drv.display_set_mode = vesa_display_set_mode;
+
+ vesa_driver.drv.bitmap_create = vesa_bitmap_create;
+ vesa_driver.drv.bitmap_destroy = vesa_bitmap_destroy;
+ vesa_driver.drv.bitmap_set_usage_hint = vesa_bitmap_set_usage_hint;
+
+ vesa_driver.drv.set_raster_op = vesa_set_raster_op;
+ vesa_driver.drv.draw_line = vesa_draw_line;
+ vesa_driver.drv.draw_rectangle = vesa_draw_rectangle;
+ vesa_driver.drv.draw_ellipse = NULL;//vesa_draw_ellipse;
+ vesa_driver.drv.draw_bitmap = vesa_draw_bitmap;
+ vesa_driver.drv.draw_bitmap_part = vesa_draw_bitmap_part;
+ vesa_driver.drv.draw_dot = vesa_draw_dot;
+
+ // Suche VGA-Karten
+ pci_devices = cdi_list_create();
+ cdi_pci_get_all_devices(pci_devices);
+ while ((pci = cdi_list_pop(pci_devices))) {
+ if (pci->class_id == 0x03 && pci->subclass_id == 0x00 &&
+ pci->interface_id == 0x00) {
+ char* name = malloc(8);
+ snprintf(name, 8, "vesa%01d", cdi_list_size(vesa_driver.drv.drv.devices));
+ struct vesa_device *dev = vesa_device_create(name, pci);
+ dev->dev.dev.driver = (struct cdi_driver*)&vesa_driver;
+ cdi_list_push(vesa_driver.drv.drv.devices, dev);
+ } else {
+ cdi_pci_device_destroy(pci);
+ }
+ }
+ cdi_list_destroy(pci_devices);
+
+ // TODO FIXME Nach init_device verschieben!
+ struct cdi_video_vesa_info_block **vesainfo_ptr;
+ vesainfo_ptr = malloc(sizeof(void*));
+ // Ohne VBE abbrechen
+ if (cdi_video_vesa_initialize(vesainfo_ptr, vesa_mode_callback) == -1) {
+ return;
+ }
+
+ // Treiber registrieren
+ cdi_video_driver_register((struct cdi_video_driver*)&vesa_driver);
+}
+
+void vesa_init_device(struct cdi_device* device) {
+ return;
+}
+
+/**
+ * Zerstoert den Treiber
+ * @param driver Pointer to the driver
+ */
+static void vesa_driver_destroy(struct cdi_driver* driver)
+{
+ cdi_video_driver_destroy((struct cdi_video_driver*)driver);
+}
diff --git a/src/modules/cdi/vesa/vesa.h b/src/modules/cdi/vesa/vesa.h
new file mode 100644
index 0000000..d6c6271
--- /dev/null
+++ b/src/modules/cdi/vesa/vesa.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander SIol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VESA_H
+#define VESA_H
+
+#include <cdi/pci.h>
+
+
+extern struct cdi_video_vesa_driver vesa_driver;
+
+struct cdi_video_vesa_driver {
+ struct cdi_video_driver drv;
+};
+
+struct vesa_device {
+ struct cdi_video_device dev;
+};
+
+struct vesa_device *vesa_device_create(char *name, struct cdi_pci_device* pci);
+
+#endif /* VESA_H */
\ No newline at end of file
--
1.6.0.4