[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Lost] [PATCH] [1/5] + cdi: Interface fuer Grafiktreiber
Ein Interface für Grafiktreiber von mir und Janosch.
Mathias
From e03c440f1e7e240e9cd9917c44b5b01c30c7c640 Mon Sep 17 00:00:00 2001
From: Mathias Gottschlag <mathias-go@xxxxxx>
Date: Tue, 14 Oct 2008 15:49:15 +0200
Subject: [PATCH] + cdi: Interface fuer Grafiktreiber
---
src/modules/cdi/include/cdi.h | 3 +-
src/modules/cdi/include/cdi/video.h | 270 ++++++++++++++++++++++++++++++++++
src/modules/cdi/lib/video/draw.c | 204 +++++++++++++++++++++++++
src/modules/cdi/lib/video/draw.h | 23 +++
src/modules/cdi/lib/video/video.c | 195 ++++++++++++++++++++++++
src/modules/cdi/lib/video/video.h | 26 ++++
src/modules/cdi/lib/video/vscreens.c | 250 +++++++++++++++++++++++++++++++
src/modules/cdi/lib/video/vscreens.h | 47 ++++++
8 files changed, 1017 insertions(+), 1 deletions(-)
create mode 100644 src/modules/cdi/include/cdi/video.h
create mode 100644 src/modules/cdi/lib/video/draw.c
create mode 100644 src/modules/cdi/lib/video/draw.h
create mode 100644 src/modules/cdi/lib/video/video.c
create mode 100644 src/modules/cdi/lib/video/video.h
create mode 100644 src/modules/cdi/lib/video/vscreens.c
create mode 100644 src/modules/cdi/lib/video/vscreens.h
diff --git a/src/modules/cdi/include/cdi.h b/src/modules/cdi/include/cdi.h
index cc3c7b9..689b550 100644
--- a/src/modules/cdi/include/cdi.h
+++ b/src/modules/cdi/include/cdi.h
@@ -20,7 +20,8 @@
typedef enum {
CDI_UNKNOWN = 0,
CDI_NETWORK = 1,
- CDI_STORAGE = 2
+ CDI_STORAGE = 2,
+ CDI_VIDEO = 3
} cdi_device_type_t;
struct cdi_driver;
diff --git a/src/modules/cdi/include/cdi/video.h b/src/modules/cdi/include/cdi/video.h
new file mode 100644
index 0000000..2191240
--- /dev/null
+++ b/src/modules/cdi/include/cdi/video.h
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2007 Mathias Gottschlag, Janosch Graef
+ *
+ * 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.
+ */
+
+#ifndef _CDI_VIDEO_H_
+#define _CDI_VIDEO_H_
+
+#include "cdi.h"
+#include "cdi/lists.h"
+
+typedef struct {
+ unsigned int width;
+ unsigned int height;
+ unsigned int depth;
+ enum {
+ CDI_VIDEO_TEXT,
+ CDI_VIDEO_GRAPHIC
+ } type;
+} cdi_video_mode_t;
+
+typedef enum {
+ CDI_VIDEO_PRIO_HIGH,
+ CDI_VIDEO_PRIO_NORMAL,
+ CDI_VIDEO_PRIO_LOW,
+} cdi_video_usage_hint_t;
+
+typedef enum {
+ CDI_VIDEO_FMT_MONO_1,
+ CDI_VIDEO_FMT_MONO_8,
+ CDI_VIDEO_FMT_R8G8B8_24,
+ CDI_VIDEO_FMT_B8G8R8_24,
+ CDI_VIDEO_FMT_R8G8B8_32,
+ CDI_VIDEO_FMT_B8G8R8_32,
+ CDI_VIDEO_FMT_R5G6B5_16,
+ CDI_VIDEO_FMT_B5G6R5_16,
+ CDI_VIDEO_FMT_R5G5B5_16,
+ CDI_VIDEO_FMT_B5G5R5_16,
+ CDI_VIDEO_FMT_GREY_8,
+} cdi_video_bitmap_format_t;
+
+struct cdi_video_bitmap {
+ int width;
+ int height;
+ cdi_video_bitmap_format_t format;
+ char *pixeldata;
+};
+
+typedef enum {
+ CDI_VIDEO_ROP_COPY,
+ CDI_VIDEO_ROP_OR,
+ CDI_VIDEO_ROP_AND,
+ CDI_VIDEO_ROP_XOR,
+} cdi_video_raster_op_t;
+
+struct cdi_video_device {
+ /// CDI-Geraet
+ struct cdi_device dev;
+
+ /// Liste der Bildschirme
+ cdi_list_t displays;
+};
+
+struct cdi_video_display {
+ /// Videogeraet, dem dieser Bildschirm angehoert
+ struct cdi_video_device *device;
+
+ /// Ob Bildschirm aktiviert ist
+ int activated;
+
+ // Derzeitiger ROP
+ cdi_video_raster_op_t raster_op;
+
+ /// Momentaner Modus
+ cdi_video_mode_t *mode;
+};
+
+struct cdi_video_driver {
+ /// CDI-Treiber
+ struct cdi_driver drv;
+
+ // Basis-Funktionen
+ /**
+ * Aktiviert einen Bildschirm
+ * @param display Bildschirm
+ * @return 0 = Erfolg; -1 = Fehlschlag
+ * @note Kann nur angewendet werden wenn der Bildschirm _nicht_ aktiviert ist
+ */
+ int (*display_enable)(struct cdi_video_display *display);
+
+ /**
+ * Deaktiviert einen Bildschirm
+ * @param display Bildschirm
+ * @return 0 = Erfolg; -1 = Fehlschlag
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ int (*display_disable)(struct cdi_video_display *display);
+
+ /**
+ * Leert einen Bildschirm
+ * @param display Bildschirm
+ * @return 0 = Erfolg; -1 = Fehlschlag
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ int (*display_clear)(struct cdi_video_display *display);
+
+ /**
+ * Setzt die Aufloesung eines Bildschirms
+ * @param display Bildschirm
+ * @param mode Modus
+ * @return 0 = Erfolg; -1 = Fehlschlag
+ */
+ int (*display_set_mode)(struct cdi_video_display *display,cdi_video_mode_t *mode);
+
+ /**
+ * Gibt eine Liste aller Modi zurueck
+ * @param display Bildschirm
+ * @return Liste aller moeglichen Modi
+ */
+ cdi_list_t (*display_get_mode_list)(struct cdi_video_display *display);
+
+ // Bitmap-Funktionen
+
+ /**
+ * Erstellt ein Bitmap
+ * @param device Videogeraet
+ * @param width Breite des Bitmaps
+ * @param height Hoehe des Bitmaps
+ * @param format Format der Pixeldaten
+ * @param data Pixel, oder 0, wenn das Bitmap vom Treiber beschrieben wird
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ struct cdi_video_bitmap *(*bitmap_create)(struct cdi_video_device *device, unsigned int width, unsigned int height, cdi_video_bitmap_format_t format, void *data);
+
+ /**
+ * Loescht ein Bitmap
+ * @param device Videogeraet
+ * @param bitmap Zu loeschendes Bitmap
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*bitmap_destroy)(struct cdi_video_device *device, struct cdi_video_bitmap *bitmap);
+
+ /**
+ * Setzt den Gebrauchsmodus eines Bitmaps (bestimmt zB, ob ein Bitmap gecacht wird)
+ * @param device Videogeraet
+ * @param bitmap Betroffenes Bitmap
+ * @param hint Hinweis auf die Priorität des Bitmaps
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*bitmap_set_usage_hint)(struct cdi_video_device *device, struct cdi_video_bitmap *bitmap, cdi_video_usage_hint_t hint);
+
+ // Zeichen-Funktionen
+
+ /**
+ * Setzt den Raster-Op für die folgenden Zeichenfunktionen.
+ * Der Raster-Op bestimmt, auf welche Art Grafik gezeichnet wird.
+ * @param display Display, auf das gezeichnet wird
+ * @param rop Raster-Op
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*set_raster_op)(struct cdi_video_display *display, cdi_video_raster_op_t rop);
+
+ /**
+ * Setzt das Ziel für alle Zeichenfunktionen. Kann entweder ein Bitmap oder der Bildschirm sein.
+ * @param display Betroffenes Display
+ * @param bitmap Zielbitmap fuer alle Zeichenfunktionen. Wenn 0, dann wird auf den Bildschirm gerendert.
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*set_target)(struct cdi_video_display *display, struct cdi_video_bitmap *bitmap);
+
+ /**
+ * Zeichnet eine Linie
+ * @param display Display, auf das gezeichnet wird
+ * @param x1 X-Koordinate des Anfangs
+ * @param y1 Y-Koordinate des Anfangs
+ * @param x1 X-Koordinate des Endpunktes
+ * @param y1 Y-Koordinate des Endpunktes
+ * @param color Farbe der Linie
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*draw_line)(struct cdi_video_display *display, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, int color);
+ /**
+ * Zeichnet ein Rechteck
+ * @param display Display, auf das gezeichnet wird
+ * @param x X-Koordinate
+ * @param y Y-Koordinate
+ * @param width Breite
+ * @param height Hoehe
+ * @param color Farbe des Rechtecks
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*draw_rectangle)(struct cdi_video_display *display, unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color);
+ /**
+ * Zeichnet eine Ellipse
+ * @param display Display, auf das gezeichnet wird
+ * @param x X-Koordinate
+ * @param y Y-Koordinate
+ * @param width Breite
+ * @param height Hoehe
+ * @param color Farbe der Ellipse
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*draw_ellipse)(struct cdi_video_display *display, unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color);
+
+ /**
+ * Kopiert einen Bereich des Bildschirminhalts
+ * @param display Display, auf das gezeichnet wird
+ * @param x X-Koordinate (Ziel)
+ * @param y Y-Koordinate (Ziel)
+ * @param srcx X-Koordinate (Quelle)
+ * @param srcy Y-Koordinate (Quelle)
+ * @param width Breite
+ * @param height Hoehe
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*copy_screen)(struct cdi_video_display *display, unsigned int x, unsigned int y, unsigned int srcx, unsigned int srcy, unsigned int width, unsigned int height);
+
+ /**
+ * Zeichnet ein Bitmap
+ * @param display Display, auf das gezeichnet wird
+ * @param bitmap Zu zeichnendes Bitmap
+ * @param x X-Koordinate
+ * @param y Y-Koordinate
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*draw_bitmap)(struct cdi_video_display *display, struct cdi_video_bitmap *bitmap, unsigned int x, unsigned int y);
+
+ /**
+ * Zeichnet ein Bitmap
+ * @param display Display, auf das gezeichnet wird
+ * @param bitmap Zu zeichnendes Bitmap
+ * @param x X-Koordinate (Ziel)
+ * @param y Y-Koordinate (Ziel)
+ * @param srcx X-Koordinate (Quelle)
+ * @param srcy Y-Koordinate (Quelle)
+ * @param width Breite
+ * @param height Hoehe
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*draw_bitmap_part)(struct cdi_video_display *display, struct cdi_video_bitmap *bitmap, unsigned int x, unsigned int y, unsigned int srcx, unsigned int srcy, unsigned int width, unsigned int height);
+
+ /**
+ * Zeichnet einen Punkt
+ * @param display Display, auf dem gezeichnet wird
+ * @param x X-Koordinate (Ziel)
+ * @param y Y-Koordinate (Ziel)
+ * @note Kann nur angewendet werden wenn der Bildschirm aktiviert ist
+ */
+ void (*draw_dot)(struct cdi_video_display *display, unsigned int x, unsigned int y, int color);
+};
+
+/**
+ * Initialisiert die Datenstrukturen fuer einen Grafikkartentreiber
+ */
+void cdi_video_driver_init(struct cdi_video_driver* driver);
+/**
+ * Deinitialisiert die Datenstrukturen fuer einen Grafikkartentreiber
+ */
+void cdi_video_driver_destroy(struct cdi_video_driver* driver);
+/**
+ * Registiert einen Grafikkartentreiber
+ */
+void cdi_video_driver_register(struct cdi_video_driver* driver);
+
+#endif
diff --git a/src/modules/cdi/lib/video/draw.c b/src/modules/cdi/lib/video/draw.c
new file mode 100644
index 0000000..56c230f
--- /dev/null
+++ b/src/modules/cdi/lib/video/draw.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2008 Mathias Gottschlag
+ *
+ * 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 "draw.h"
+#include "vscreens.h"
+#include "video.h"
+#include <video/commands.h>
+#include <video/drawing.h>
+#include <cdi/video.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int upload_bitmap(int card, int index, int pid, int width, int height, int format, int datalength, void *data)
+{
+ // Treiberfunktion aufrufen
+ struct vscreen *vscreen = get_vscreen(card, index);
+ if (!vscreen) return 0;
+ if (vscreen->owner != pid) return 0;
+ struct cdi_video_bitmap *bitmap = videocards[card].driver->bitmap_create(videocards[card].card, width, height, format, data);
+ if (!bitmap) return 0;
+
+ // Bitmap an Liste anhaengen
+ int id = ++vscreen->maxbitmapid;
+ struct vscreen_bitmap *vsbitmap = malloc(sizeof(struct vscreen_bitmap));
+ vsbitmap->bitmap = bitmap;
+ vsbitmap->id = id;
+ vscreen->bitmaps = cdi_list_push(vscreen->bitmaps, vsbitmap);
+ return id;
+}
+int destroy_bitmap(int card, int index, int pid, int bitmap)
+{
+ struct vscreen *vscreen = get_vscreen(card, index);
+ if (!vscreen) return 0;
+ if (vscreen->owner != pid) return 0;
+ // Aus Liste heraussuchen und loeschen
+ struct vscreen_bitmap *vsbitmap = 0;
+ int i;
+ for (i = 0; i < cdi_list_size(vscreen->bitmaps); i++) {
+ struct vscreen_bitmap *tmp = cdi_list_get(vscreen->bitmaps, i);
+ if (tmp->id == bitmap) {
+ vsbitmap = tmp;
+ cdi_list_remove(vscreen->bitmaps, i);
+ break;
+ }
+ }
+ if (!vsbitmap) return 0;
+
+ // Treiberfunktion aufrufen
+ videocards[card].driver->bitmap_destroy(videocards[card].card, vsbitmap->bitmap);
+ free(vsbitmap);
+ return 1;
+}
+int destroy_all_bitmaps(int card, int index, int pid)
+{
+ struct vscreen *vscreen = get_vscreen(card, index);
+ if (!vscreen) return 0;
+ if (vscreen->owner != pid) return 0;
+ // Alle Bitmaps aus der Liste loeschen
+ struct vscreen_bitmap *vsbitmap;
+ while ((vsbitmap = cdi_list_pop(vscreen->bitmaps)) != 0) {
+ videocards[card].driver->bitmap_destroy(videocards[card].card, vsbitmap->bitmap);
+ free(vsbitmap);
+ }
+ return 1;
+}
+struct cdi_video_bitmap *get_bitmap(int card, int index, int id)
+{
+ struct vscreen *vscreen = get_vscreen(card, index);
+ if (!vscreen) return 0;
+ int i;
+ for (i = 0; i < cdi_list_size(vscreen->bitmaps); i++) {
+ struct vscreen_bitmap *vsbitmap = cdi_list_get(vscreen->bitmaps, i);
+ if (vsbitmap->id == id) return vsbitmap->bitmap;
+ }
+ return 0;
+}
+
+int video_do_buffer(int card, int index, int screen, int pid, unsigned int length)
+{
+ // Screen/Bildschirm heraussuchen
+ if (index != videocards[card].activevscreen) return 0;
+ struct vscreen *vscreen = get_vscreen(card, index);
+ if (!vscreen) return 0;
+ if (vscreen->owner != pid) return 0;
+ struct cdi_video_display *display = cdi_list_get(videocards[card].card->displays, screen);
+ if (!display) return 0;
+
+ // Buffer
+ if (!vscreen->cmdbufferid) {
+ return 0;
+ }
+ if (!length) return 1;
+ if (length > 64 * 1024) length = 64 * 1024;
+
+ char *buffer = vscreen->cmdbuffer;
+
+ // Buffer parsen
+ while (length > 0) {
+ if ((length >= 2) && (buffer[0] == VIDEO_CMD_SET_ROP)) {
+ cdi_video_raster_op_t rop = CDI_VIDEO_ROP_COPY;
+ if (buffer[1] == ROP_AND) {
+ rop = CDI_VIDEO_ROP_AND;
+ } else if (buffer[1] == ROP_OR) {
+ rop = CDI_VIDEO_ROP_OR;
+ } else if (buffer[1] == ROP_XOR) {
+ rop = CDI_VIDEO_ROP_XOR;
+ }
+ videocards[card].driver->set_raster_op(display, rop);
+ buffer += 2;
+ length -= 2;
+ } else if ((length >= 12) && (buffer[0] == VIDEO_CMD_DRAW_RECT)) {
+ unsigned int color = *((unsigned int*)(buffer + 1)) & 0xFFFFFF;
+ unsigned short x = *((unsigned short*)(buffer + 4));
+ unsigned short y = *((unsigned short*)(buffer + 6));
+ unsigned short width = *((unsigned short*)(buffer + 8));
+ unsigned short height = *((unsigned short*)(buffer + 10));
+ videocards[card].driver->draw_rectangle(display, x, y, width, height, color);
+ buffer += 12;
+ length -= 12;
+ } else if ((length >= 12) && (buffer[0] == VIDEO_CMD_DRAW_ELLIPSE)) {
+ unsigned int color = *((unsigned int*)(buffer + 1)) & 0xFFFFFF;
+ unsigned short x = *((unsigned short*)(buffer + 4));
+ unsigned short y = *((unsigned short*)(buffer + 6));
+ unsigned short width = *((unsigned short*)(buffer + 8));
+ unsigned short height = *((unsigned short*)(buffer + 10));
+ videocards[card].driver->draw_ellipse(display, x, y, width, height, color);
+ buffer += 12;
+ length -= 12;
+ } else if ((length >= 12) && (buffer[0] == VIDEO_CMD_DRAW_LINE)) {
+ unsigned int color = *((unsigned int*)(buffer + 1)) & 0xFFFFFF;
+ unsigned short x1 = *((unsigned short*)(buffer + 4));
+ unsigned short y1 = *((unsigned short*)(buffer + 6));
+ unsigned short x2 = *((unsigned short*)(buffer + 8));
+ unsigned short y2 = *((unsigned short*)(buffer + 10));
+ videocards[card].driver->draw_line(display, x1, y1, x2, y2, color);
+ buffer += 12;
+ length -= 12;
+ } else if ((length >= 8) && (buffer[0] == VIDEO_CMD_DRAW_DOT)) {
+ unsigned int color = *((unsigned int*)(buffer + 1)) & 0xFFFFFF;
+ unsigned short x = *((unsigned short*)(buffer + 4));
+ unsigned short y = *((unsigned short*)(buffer + 6));
+ videocards[card].driver->draw_dot(display, x, y, color);
+ buffer += 8;
+ length -= 8;
+ } else if ((length >= 9) && (buffer[0] == VIDEO_CMD_DRAW_BITMAP)) {
+ unsigned int bitmapid = *((unsigned int*)(buffer + 1));
+ unsigned short x = *((unsigned short*)(buffer + 5));
+ unsigned short y = *((unsigned short*)(buffer + 7));
+ // Bitmap heraussuchen
+ struct cdi_video_bitmap *bitmap = get_bitmap(card, index, bitmapid);
+ // Zeichnen
+ if (bitmap) {
+ videocards[card].driver->draw_bitmap(display, bitmap, x, y);
+ } else {
+ printf("[ cdi/video ] Bitmap nicht gefunden!\n");
+ }
+ buffer += 9;
+ length -= 9;
+ } else if ((length >= 17) && (buffer[0] == VIDEO_CMD_DRAW_BITMAP_PART)) {
+ unsigned int bitmapid = *((unsigned int*)(buffer + 1));
+ unsigned short x = *((unsigned short*)(buffer + 5));
+ unsigned short y = *((unsigned short*)(buffer + 7));
+ unsigned short srcx = *((unsigned short*)(buffer + 9));
+ unsigned short srcy = *((unsigned short*)(buffer + 11));
+ unsigned short width = *((unsigned short*)(buffer + 13));
+ unsigned short height = *((unsigned short*)(buffer + 15));
+ // Bitmap heraussuchen
+ struct cdi_video_bitmap *bitmap = get_bitmap(card, index, bitmapid);
+ // Zeichnen
+ if (bitmap) {
+ videocards[card].driver->draw_bitmap_part(display, bitmap, x, y, srcx, srcy, width, height);
+ } else {
+ printf("[ cdi/video ] Bitmap nicht gefunden!\n");
+ }
+ buffer += 17;
+ length -= 17;
+ } else if ((length >= 13) && (buffer[0] == VIDEO_CMD_COPY_SCREEN)) {
+ unsigned short x = *((unsigned short*)(buffer + 1));
+ unsigned short y = *((unsigned short*)(buffer + 3));
+ unsigned short srcx = *((unsigned short*)(buffer + 5));
+ unsigned short srcy = *((unsigned short*)(buffer + 7));
+ unsigned short width = *((unsigned short*)(buffer + 9));
+ unsigned short height = *((unsigned short*)(buffer + 11));
+ // Zeichnen
+ videocards[card].driver->copy_screen(display, x, y, srcx, srcy, width, height);
+ buffer += 13;
+ length -= 13;
+ } else {
+ // TODO
+ break;
+ }
+ }
+
+ return 1;
+}
+
+
diff --git a/src/modules/cdi/lib/video/draw.h b/src/modules/cdi/lib/video/draw.h
new file mode 100644
index 0000000..7186064
--- /dev/null
+++ b/src/modules/cdi/lib/video/draw.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2008 Mathias Gottschlag
+ *
+ * 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.
+ */
+
+#ifndef _DRAW_H_
+#define _DRAW_H_
+
+#include <cdi/video.h>
+
+int upload_bitmap(int card, int index, int pid, int width, int height, int format, int datalength, void *data);
+int destroy_bitmap(int card, int index, int pid, int bitmap);
+int destroy_all_bitmaps(int card, int index, int pid);
+struct cdi_video_bitmap *get_bitmap(int card, int index, int id);
+
+int video_do_buffer(int card, int index, int screen, int pid, unsigned int length);
+
+#endif
diff --git a/src/modules/cdi/lib/video/video.c b/src/modules/cdi/lib/video/video.c
new file mode 100644
index 0000000..b781bb0
--- /dev/null
+++ b/src/modules/cdi/lib/video/video.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2008 Mathias Gottschlag
+ *
+ * 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 <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lostio.h>
+#include <video/commands.h>
+#include <rpc.h>
+#include <syscall.h>
+
+#include "video.h"
+#include "vscreens.h"
+#include "draw.h"
+
+int videocard_count = 0;
+struct cdi_video_driver* videodriver = 0;
+
+//Interface über RPC
+void rpc_video_interface(pid_t pid,
+ dword correlation_id,
+ size_t data_size,
+ void* data);
+
+/**
+ * Initialisiert die Datenstrukturen fuer einen Grafikkartentreiber
+ */
+void cdi_video_driver_init(struct cdi_video_driver* driver)
+{
+ cdi_driver_init((struct cdi_driver*) driver);
+
+ register_message_handler("VIDEODRV", rpc_video_interface);
+}
+
+/**
+ * Deinitialisiert die Datenstrukturen fuer einen Grafikkartentreiber
+ */
+void cdi_video_driver_destroy(struct cdi_video_driver* driver)
+{
+ cdi_driver_destroy((struct cdi_driver*) driver);
+}
+
+/**
+ * Registiert einen Grafikkartentreiber
+ */
+void cdi_video_driver_register(struct cdi_video_driver* driver)
+{
+ videodriver = driver;
+ cdi_driver_register((struct cdi_driver*) driver);
+
+ int i;
+ for (i = 0; i < cdi_list_size(driver->drv.devices); i++) {
+ videocards[i].card = cdi_list_get(driver->drv.devices, i);
+ videocards[i].activevscreen = -1;
+ videocards[i].vscreens = cdi_list_create();
+ videocards[i].driver = driver;
+ videocard_count++;
+ }
+}
+
+void rpc_video_interface(pid_t pid,
+ dword correlation_id,
+ size_t data_size,
+ void* data)
+{
+ int result = 1;
+ // Befehlsinformation auslesen
+ dword *command = data;
+ if (data_size < sizeof(int) * 2) {
+ rpc_send_dword_response(pid, correlation_id, 0);
+ return;
+ }
+
+ dword device_number = command[0];
+ // Anzahl der Devices zurueckgeben
+ if (device_number == 0xFFFFFFFF) {
+ rpc_send_dword_response(pid, correlation_id, videocard_count);
+ return;
+ }
+ // Kaputte Geraetenummer
+ if (device_number >= videocard_count) {
+ rpc_send_dword_response(pid, correlation_id, 0);
+ return;
+ }
+ // Befehl ausführen
+ switch (command[1]) {
+ case VIDEO_ADD_VSCREEN:
+ if (data_size < sizeof(int) * 4) {
+ result = 0;
+ } else {
+ result = vscreen_add(device_number, command[2], command[3]);
+ }
+ break;
+ case VIDEO_REMOVE_VSCREEN:
+ if (data_size < sizeof(int) * 3) {
+ result = 0;
+ } else {
+ vscreen_remove(device_number, command[2]);
+ }
+ break;
+ case VIDEO_SET_ACTIVE_VSCREEN:
+ if (data_size < sizeof(int) * 3) {
+ result = 0;
+ } else {
+ vscreen_set_active(device_number, command[2]);
+ }
+ break;
+ case VIDEO_GET_ACTIVE_VSCREEN:
+ result = vscreen_get_active(device_number);
+ break;
+
+ case VIDEO_SET_RESOLUTION:
+ if (data_size < sizeof(int) * 8) {
+ result = 0;
+ } else {
+ int index = command[2];
+ int screen = command[3];
+ int width = command[4];
+ int height = command[5];
+ int depth = command[6];
+ int text = command[7];
+ result = vscreen_set_resolution(device_number, index, screen, pid,
+ width, height, depth, text);
+ }
+ break;
+ case VIDEO_GET_RESOLUTION:
+ break;
+ case VIDEO_GET_RESOLUTION_LIST:
+ break;
+ case VIDEO_UPLOAD_BITMAP:
+ if (data_size < sizeof(int) * 7) {
+ result = 0;
+ } else {
+ int index = command[2];
+ int width = command[3];
+ int height = command[4];
+ int format = command[5];
+ int length = command[6];
+ if ((length != 0) && (data_size < sizeof(int) * 7 + length)) {
+ result = 0;
+ } else {
+ void *data = 0;
+ if (length) data = &command[7];
+ result = upload_bitmap(device_number, index, pid, width, height, format, length, data);
+ }
+ }
+ break;
+ case VIDEO_DESTROY_BITMAP:
+ if (data_size < sizeof(int) * 4) {
+ result = 0;
+ } else {
+ int index = command[2];
+ int bitmap = command[3];
+ result = destroy_bitmap(device_number, index, pid, bitmap);
+ }
+ break;
+ break;
+ case VIDEO_DESTROY_ALL_BITMAPS:
+ if (data_size < sizeof(int) * 3) {
+ result = 0;
+ } else {
+ int index = command[2];
+ result = destroy_all_bitmaps(device_number, index, pid);
+ }
+ break;
+ case VIDEO_COMMAND_STREAM:
+ if (data_size < sizeof(int) * 5) {
+ result = 0;
+ } else {
+ int index = command[2];
+ int screen = command[3];
+ int length = command[4];
+ result = video_do_buffer(device_number, index, screen, pid, length);
+ }
+ break;
+ case VIDEO_GET_COMMAND_BUFFER:
+ if (data_size < sizeof(int) * 2) {
+ result = 0;
+ } else {
+ result = vscreen_get_command_buffer(device_number, command[2], pid);
+ }
+ break;
+ }
+
+ rpc_send_dword_response(pid, correlation_id, result);
+}
+
diff --git a/src/modules/cdi/lib/video/video.h b/src/modules/cdi/lib/video/video.h
new file mode 100644
index 0000000..cebde01
--- /dev/null
+++ b/src/modules/cdi/lib/video/video.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2008 Mathias Gottschlag
+ *
+ * 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.
+ */
+
+#ifndef VIDEO_H
+#define VIDEO_H
+
+#include "vscreens.h"
+
+extern int videocard_count;
+struct {
+ struct cdi_video_device* card;
+ int activevscreen;
+ cdi_list_t vscreens;
+ struct cdi_video_driver* driver;
+} videocards[10];
+// FIXME: Dynamische Anzahl
+
+#endif
+
diff --git a/src/modules/cdi/lib/video/vscreens.c b/src/modules/cdi/lib/video/vscreens.c
new file mode 100644
index 0000000..b338cce
--- /dev/null
+++ b/src/modules/cdi/lib/video/vscreens.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2008 Mathias Gottschlag
+ *
+ * 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 "vscreens.h"
+#include "video.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <video/commands.h>
+#include <rpc.h>
+#include <syscall.h>
+#include "cdi/bios.h"
+
+struct vscreen *get_vscreen(int card, int index)
+{
+ int i;
+ for (i = 0; i < cdi_list_size(videocards[card].vscreens); i++) {
+ struct vscreen *screen = cdi_list_get(videocards[card].vscreens, i);
+ if (screen->index == index) {
+ return screen;
+ }
+ }
+ return 0;
+}
+
+int vscreen_add(int card, int index, int pid)
+{
+ struct vscreen *screen = get_vscreen(card, index);
+ if (!screen) {
+ screen = malloc(sizeof(struct vscreen));
+ screen->screencount = 0;
+ screen->mode = 0;
+ screen->owner = pid;
+ screen->index = index;
+ screen->cmdbufferid = 0;
+ screen->cmdbuffer = 0;
+ screen->maxbitmapid = 0;
+ screen->bitmaps = cdi_list_create();
+ videocards[card].vscreens = cdi_list_push(videocards[card].vscreens, screen);
+ printf("Neuer vscreen(%d), PID = %d.\n", index, pid);
+ if (videocards[card].activevscreen == -1) vscreen_set_active(card, index);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+void vscreen_remove(int card, int index)
+{
+ int i;
+ struct vscreen *screen;
+ for (i = 0; i < cdi_list_size(videocards[card].vscreens); i++) {
+ screen = cdi_list_get(videocards[card].vscreens, i);
+ if (screen->index == index) {
+ if (videocards[card].activevscreen == index) vscreen_set_active(card, 0);
+ // TODO: Daten loeschen (Bitmaps)
+
+ // Vscreen entfernen
+ if (screen->mode) free(screen->mode);
+ close_shared_memory(screen->cmdbufferid);
+ videocards[card].vscreens = cdi_list_remove(videocards[card].vscreens, i);
+ free(screen);
+ return;
+ }
+ }
+}
+void vscreen_set_active(int card, int index)
+{
+ // Virtuelle Screens raussuchen
+ struct vscreen *oldvscreen = get_vscreen(card, videocards[card].activevscreen);
+ struct vscreen *newvscreen = get_vscreen(card, index);
+ if (newvscreen == oldvscreen) return;
+
+ if (oldvscreen && oldvscreen->owner) {
+ // Benutzer des Screens mitteilen, dass er ab jetzt ungültig ist
+ int command[1];
+ command[0] = VIDEO_CLIENT_DEACTIVATE;
+ rpc_get_dword(oldvscreen->owner,
+ "VIDEOLIB",
+ sizeof(int),
+ (char*)command);
+ }
+
+ // Bildschirmauflösungen ändern / Bildschirme (de)aktivieren
+ if (newvscreen && oldvscreen) {
+ printf("Wechsle Aufloesung.\n");
+ int mindisplays = oldvscreen->screencount;
+ if (newvscreen->screencount < mindisplays) mindisplays = newvscreen->screencount;
+
+ int i;
+ for (i = 0; i < mindisplays; i++) {
+ struct cdi_video_display *display = cdi_list_get(videocards[card].card->displays, i);
+ if (!display) {
+ break;
+ }
+ if (oldvscreen->mode[i] && newvscreen->mode[i]) {
+ videocards[card].driver->display_set_mode(display, newvscreen->mode[i]);
+ } else if (oldvscreen->mode[i]) {
+ videocards[card].driver->display_disable(display);
+ } else if (newvscreen->mode[i]) {
+ videocards[card].driver->display_set_mode(display, newvscreen->mode[i]);
+ videocards[card].driver->display_enable(display);
+ }
+ }
+ if (newvscreen->screencount > oldvscreen->screencount) {
+ for (i = mindisplays; i < newvscreen->screencount; i++) {
+ struct cdi_video_display *display = cdi_list_get(videocards[card].card->displays, i);
+ if (!display) {
+ break;
+ }
+ if (newvscreen->mode[i]) {
+ videocards[card].driver->display_set_mode(display, newvscreen->mode[i]);
+ videocards[card].driver->display_enable(display);
+ }
+ }
+ } else {
+ for (i = mindisplays; i < oldvscreen->screencount; i++) {
+ struct cdi_video_display *display = cdi_list_get(videocards[card].card->displays, i);
+ if (!display) {
+ break;
+ }
+ if (oldvscreen->mode[i]) {
+ videocards[card].driver->display_disable(display);
+ }
+ }
+ }
+ } else if (newvscreen) {
+ int i;
+ for (i = 0; i < newvscreen->screencount; i++) {
+ struct cdi_video_display *display = cdi_list_get(videocards[card].card->displays, i);
+ if (!display) {
+ break;
+ }
+ if (newvscreen->mode[i]) {
+ videocards[card].driver->display_set_mode(display, newvscreen->mode[i]);
+ videocards[card].driver->display_enable(display);
+ }
+ }
+ } else if (oldvscreen) {
+ int i;
+ for (i = 0; i < oldvscreen->screencount; i++) {
+ struct cdi_video_display *display = cdi_list_get(videocards[card].card->displays, i);
+ if (!display) {
+ break;
+ }
+ if (oldvscreen->mode[i]) {
+ videocards[card].driver->display_disable(display);
+ }
+ }
+ }
+ videocards[card].activevscreen = index;
+
+ if (newvscreen && newvscreen->owner) {
+ // Benutzer des Screens mitteilen, dass er ab jetzt gültig ist
+ int command[1];
+ command[0] = VIDEO_CLIENT_ACTIVATE;
+ rpc_get_dword(newvscreen->owner,
+ "VIDEOLIB",
+ sizeof(int),
+ (char*)command);
+ }
+}
+int vscreen_get_active(int card)
+{
+ return videocards[card].activevscreen;
+}
+
+int vscreen_set_resolution(int card, int index, int screen, int pid, int width, int height, int bpp, int text)
+{
+ printf("Setze Aufloesung (%d).\n", index);
+ // Screen/Bildschirm heraussuchen
+ struct vscreen *vscreen = get_vscreen(card, index);
+ if (!vscreen) return 0;
+ if (vscreen->owner != pid) return 0;
+ struct cdi_video_display *display = cdi_list_get(videocards[card].card->displays, screen);
+ if (!display) return 0;
+
+ // Platz schaffen fuer Modus
+ if (vscreen->screencount <= screen) {
+ vscreen->mode = realloc(vscreen->mode, (screen + 1) * sizeof(void*));
+ memset(vscreen->mode + vscreen->screencount, 0x00, (screen + 1 - vscreen->screencount) * sizeof(void*));
+ vscreen->screencount = screen + 1;
+ }
+
+ // Liste mit Modi laden und Modus heraussuchen
+ cdi_video_mode_t *newmode = 0;
+ cdi_list_t modes = videocards[card].driver->display_get_mode_list(display);
+ int i;
+ for (i = 0; i < cdi_list_size(modes); i++) {
+ cdi_video_mode_t *mode = cdi_list_get(modes, i);
+ if ((mode->width == width) && (mode->height == height) && (mode->depth == bpp) && (mode->type == 1 - text))
+ {
+ newmode = mode;
+ break;
+ }
+ }
+
+ if (!newmode) {
+ // Bestmoeglichen Modus waehlen
+ // TODO
+ }
+
+ if (!newmode) {
+ printf("Kein Modus gefunden.\n");
+ return 0;
+ }
+
+ cdi_video_mode_t *oldmode = vscreen->mode[screen];
+ vscreen->mode[screen] = newmode;
+
+ if (videocards[card].activevscreen == index) {
+ // Bildschirmaufloesung setzen
+ videocards[card].driver->display_set_mode(display, newmode);
+ if (!oldmode) {
+ videocards[card].driver->display_enable(display);
+ }
+ }
+
+ return 1;
+}
+cdi_video_mode_t *vscreen_get_resolution(int card, int index, int screen)
+{
+ return 0;
+}
+
+dword vscreen_get_command_buffer(int card, int index, int pid)
+{
+ // Screen/Bildschirm heraussuchen
+ struct vscreen *vscreen = get_vscreen(card, index);
+ if (!vscreen) return 0;
+ if (vscreen->owner != pid) return 0;
+
+ // Schon erstellt?
+ if (vscreen->cmdbufferid) {
+ return vscreen->cmdbufferid;
+ }
+
+ // Neuen Buffer erstellen
+ // FIXME: Ne feste Groesse ist dumm.
+ vscreen->cmdbufferid = create_shared_memory(64 * 1024);
+ vscreen->cmdbuffer = open_shared_memory(vscreen->cmdbufferid);
+ return vscreen->cmdbufferid;
+}
+
diff --git a/src/modules/cdi/lib/video/vscreens.h b/src/modules/cdi/lib/video/vscreens.h
new file mode 100644
index 0000000..1a807b1
--- /dev/null
+++ b/src/modules/cdi/lib/video/vscreens.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008 Mathias Gottschlag
+ *
+ * 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.
+ */
+
+#ifndef VSCREENS_H
+#define VSCREENS_H
+
+#include <types.h>
+
+#include "cdi/video.h"
+
+struct vscreen_bitmap {
+ int id;
+ struct cdi_video_bitmap *bitmap;
+};
+
+struct vscreen {
+ int screencount;
+ cdi_video_mode_t **mode;
+ pid_t owner;
+ int index;
+ dword cmdbufferid;
+ char *cmdbuffer;
+ int maxbitmapid;
+ cdi_list_t bitmaps;
+};
+
+struct vscreen *get_vscreen(int card, int index);
+
+int vscreen_add(int card, int index, int pid);
+void vscreen_remove(int card, int index);
+void vscreen_set_active(int card, int index);
+int vscreen_get_active(int card);
+
+int vscreen_set_resolution(int card, int index, int screen, int pid, int width, int height, int bpp, int text);
+cdi_video_mode_t *vscreen_get_resolution(int card, int index, int screen);
+
+dword vscreen_get_command_buffer(int card, int index, int pid);
+
+#endif
+
--
1.5.4.3