home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Video module for GTK+
- *
- * This writes to the GtkDrawingArea inside the v9t9_window
- */
- #include <conf.h>
-
- #if defined(UNDER_UNIX)
- #include <gdk/gdkx.h>
- #elif defined(UNDER_WIN32)
- #include "winv9t9.h"
- #define WIN32_LEAN_AND_MEAN
- #include <gdk/win32/gdkwin32.h>
- #endif
-
- #include <gtk/gtk.h>
-
- #include "gtkinterface.h"
- #include "gtkcallbacks.h"
- #include "gtkloop.h"
-
- #include "v9t9_common.h"
- #include "video.h"
- #include "vdp.h"
- #include "memory.h"
- #include "9900.h"
- #include "v9t9.h"
-
- #define _L LOG_VIDEO
-
- static GdkColor v9t9_gdk_palette[17];
-
- // GC for each color we'll display...
- static GdkGC *v9t9_gdk_colors[17];
-
- // true if colors 0 and 17 can be changed without redrawing
- static gboolean v9t9_gdk_paletted;
-
- // mapping from TI color (0=bg, 17=fg, others the same)
- // to v9t9_gdk_color[] entry
- static gint cmap[17];
-
- static void
- video_setpaletteentry(int index, int c)
- {
- logger(_L | L_1, "Setting index %d to color %d\n", index, c);
-
- if (v9t9_gdk_paletted) {
- /* !!! */
- } else {
- cmap[index] = c == 0 ? vdpbg : c == 16 ? vdpfg : c;
- }
- }
-
- static void
- video_updatepalette(void)
- {
- int x;
-
- for (x = 1; x < 16; x++)
- video_setpaletteentry(x, x);
- video_setpaletteentry(0, vdpbg);
- video_setpaletteentry(16, vdpfg);
- }
-
- static vmResult system_gtkvideo_detect(void);
- static vmResult system_gtkvideo_init(void);
- static vmResult system_gtkvideo_enable(void);
- static vmResult system_gtkvideo_disable(void);
- static vmResult system_gtkvideo_restart(void);
- static vmResult system_gtkvideo_restop(void);
- static vmResult system_gtkvideo_term(void);
-
-
- static vmResult
- gtkvideo_detect(void)
- {
- return system_gtkvideo_detect();
- }
-
- static vmResult
- gtkvideo_init(void)
- {
- int i;
-
- for (i = 1; i < 16; i++)
- {
- v9t9_gdk_palette[i].red = RGB_8_TO_16(vdp_palette[i][0]);
- v9t9_gdk_palette[i].green = RGB_8_TO_16(vdp_palette[i][1]);
- v9t9_gdk_palette[i].blue = RGB_8_TO_16(vdp_palette[i][2]);
- }
-
- features |= FE_SHOWVIDEO;
- my_assert(v9t9_drawing_area);
- return system_gtkvideo_init();
- }
-
- static vmResult
- gtkvideo_enable(void)
- {
- if (VALID_WINDOW(v9t9_window)) {
- gtk_widget_show(v9t9_window);
- return system_gtkvideo_enable();
- } else
- return vmInternalError;
- }
-
- static vmResult
- gtkvideo_disable(void)
- {
- vmResult result;
- if (VALID_WINDOW(v9t9_window)) {
- if ((result = system_gtkvideo_disable()) != vmOk)
- return result;
- gtk_widget_hide(v9t9_window);
- return vmOk;
- } else
- return vmInternalError;
- }
-
- static vmResult
- gtkvideo_restart(void)
- {
- // allocate our colors
- GdkColormap *map;
- int i;
-
- if (!VALID_WINDOW(v9t9_window)) {
- return vmInternalError;
- }
-
- map = gdk_window_get_colormap(v9t9_drawing_area->window);
-
- // we must get the middle colors
- for (i = 1; i <= 15; i++) {
- if (!gdk_colormap_alloc_color(map,
- v9t9_gdk_palette + i,
- false /* writeable */,
- true /* best_match */))
- {
- logger(_L|LOG_USER|LOG_ERROR, "Could not allocate 15 colors\n");
- return vmInternalError;
- }
- }
-
- // this appears to work, but shouldn't
- #if 0
- // try to get bg and fg palettized
- gdk_colormap_alloc_colors(map,
- v9t9_gdk_palette,
- 1,
- true /* writeable */,
- true /* best_match */,
- &success);
-
- if (success) {
- gdk_colormap_alloc_colors(map,
- v9t9_gdk_palette+16,
- 1,
- true /* writeable */,
- true /* best_match */,
- &success);
- if (success) {
- v9t9_gdk_paletted = true;
- logger(_L|LOG_USER, "Got writeable colors for bg/fg\n");
- } else {
- v9t9_gdk_paletted = false;
- gdk_colormap_free_colors(map, v9t9_gdk_palette, 1);
- }
- } else
- #endif
- {
- v9t9_gdk_paletted = false;
- logger(_L, "No writeable colors available\n");
- }
-
- for (i = 0; i < 17; i++) {
- logger(_L|L_1, "Color %d is %08X\n", i, v9t9_gdk_palette[i].pixel);
- }
-
- // Set up the colors in GCs that stay allocated
- for (i = 0; i < 17; i++) {
- v9t9_gdk_colors[i] = gdk_gc_new(v9t9_drawing_area->window);
- gdk_gc_set_foreground(v9t9_gdk_colors[i], v9t9_gdk_palette + i);
- }
-
- return system_gtkvideo_restart();
- }
-
- static vmResult
- gtkvideo_restop(void)
- {
- GdkColormap *map;
- int i;
- vmResult result;
-
- if (!VALID_WINDOW(v9t9_window)) {
- return vmInternalError;
- }
-
- result = system_gtkvideo_restop();
- if (result != vmOk)
- return result;
-
- // free our colors
- for (i = 0; i < 17; i++) {
- gdk_gc_unref(v9t9_gdk_colors[i]);
- v9t9_gdk_colors[i] = 0L;
- }
-
- map = gdk_window_get_colormap(v9t9_drawing_area->window);
- if (v9t9_gdk_paletted) {
- gdk_colormap_free_colors(map, v9t9_gdk_palette, 1);
- gdk_colormap_free_colors(map, v9t9_gdk_palette+16, 1);
- }
- gdk_colormap_free_colors(map, v9t9_gdk_palette+1, 15);
-
- return vmOk;
- }
-
- static vmResult
- gtkvideo_term(void)
- {
- if (!VALID_WINDOW(v9t9_window)) {
- return vmInternalError;
- }
-
- system_gtkvideo_term();
- gtk_widget_unref(v9t9_window);
- v9t9_drawing_area = 0L;
- v9t9_window = 0L;
- return vmOk;
- }
-
- /**************/
- #if 0
- #pragma mark -
- #pragma mark [ X Windows ]
- #endif
-
- #if defined(UNDER_UNIX)
-
- static vmResult
- system_gtkvideo_detect(void)
- {
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_init(void)
- {
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_enable(void)
- {
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_disable(void)
- {
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_restart(void)
- {
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_restop(void)
- {
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_term(void)
- {
- return vmOk;
- }
-
- /*
- * Use X11 stuff directly, since it's really fast
- */
- static void
- gtk_update_area(struct updateblock *ptr, int num)
- {
- int width = 8;
- u8 *blk;
- XRectangle points[17][64], *pptr[17];
- int rects = 0, pixels = 0;
- int xoffs = (256 - GTK_x_size) / 2;
- int i;
- int j;
-
- Display *display;
- Window window;
-
- int total = num, solid = 0;
-
- /*
- * configure/expose callback should have been sent so we can
- * figure out where it is
- */
-
- display = GDK_WINDOW_XDISPLAY(v9t9_drawing_area->window);
- window = GDK_WINDOW_XWINDOW(v9t9_drawing_area->window);
- my_assert(v9t9_drawing_area);
-
- if (!num)
- return;
-
- while (num--) {
- u8 c = 0;
- int d;
-
- ptr->r *= GTK_y_mult;
- ptr->c = (ptr->c + xoffs) * GTK_x_mult;
-
- if (video_block_is_solid(ptr, !v9t9_gdk_paletted, &c) &&
- v9t9_gdk_colors[cmap[c]]) {
- XFillRectangle(display, window,
- GDK_GC_XGC(v9t9_gdk_colors[cmap[c]]),
- ptr->c,
- ptr->r,
- GTK_x_mult * width,
- GTK_y_mult * 8);
- solid++;
- }
- else
- {
- /* Reset lists for each color (remember text mode has color==16) */
- for (c = 0; c < 17; c++)
- pptr[c] = points[c];
-
- /* Generate a list of rectangles for each color
- in the 8x8 block */
- for (i = 0; i < 8; i++) {
- j = 0;
- while (j < width) {
- /* Find the longest run of pixels of this color */
- c = ptr->data[j];
- d = 1;
- while (j + d < width && ptr->data[j + d] == c)
- d++;
-
- pptr[c]->x = ptr->c + j * GTK_x_mult;
- pptr[c]->y = ptr->r + i * GTK_y_mult;
- pptr[c]->width = GTK_x_mult * d;
- pptr[c]->height = GTK_y_mult;
-
- rects++;
- pixels += pptr[c]->width * pptr[c]->height;
-
- pptr[c]++;
- j += d;
- }
- ptr->data += UPDATEBLOCK_ROW_STRIDE;
- }
-
- for (c = 0; c <= 16; c++) {
- if (pptr[c] > points[c] && v9t9_gdk_colors[cmap[c]]) {
- XFillRectangles(display, window,
- GDK_GC_XGC(v9t9_gdk_colors[cmap[c]]),
- points[c],
- pptr[c] - points[c]);
- }
- }
-
- }
-
- ptr++;
- }
-
- // XFlush(GDK_WINDOW_XDISPLAY(v9t9_drawing_area->window));
- logger(_L | L_2, "Drew %d rects, %d pixels\n", rects, pixels);
-
- logger(_L|L_2, "%d/%d solid\n", solid, total);
- }
-
- #endif
-
- /**************/
-
- #if 0
- #pragma mark -
- #pragma mark [ Win32 ]
- #endif
-
- #if defined(UNDER_WIN32)
-
- static GdkVisual *gdkvisual;
- static GdkImage *gdkimage;
-
- static vmResult
- system_gtkvideo_detect(void)
- {
- /* get our visual, 8-bit paletted */
-
- gdkvisual = gdk_visual_get_best();
-
- if (!gdkvisual)
- {
- logger(_L|LOG_USER|LOG_ERROR, "Could not get visual\n");
- return vmNotAvailable;
- }
-
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_init(void)
- {
-
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_enable(void)
- {
- /* create a GdkImage for the v9t9 screen */
-
- gdkimage = gdk_image_new(GDK_IMAGE_SHARED_PIXMAP, gdkvisual, 256*4, 256*4);
- if (!gdkimage)
- {
- logger(_L|LOG_USER|LOG_ERROR, "Could not get image\n");
- return vmNotAvailable;
- }
-
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_disable(void)
- {
- gdk_image_unref(gdkimage);
-
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_restart(void)
- {
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_restop(void)
- {
- return vmOk;
- }
-
- static vmResult
- system_gtkvideo_term(void)
- {
- return vmOk;
- }
-
- #define MSBFirst 1
- #define x11_24_order 0
- int vwxsz;
-
- #define vwxm GTK_x_mult
- #define vwym GTK_y_mult
- #define cmapping(x) v9t9_gdk_palette[cmap[x]].pixel
-
- #include "video_X_draw.h"
-
- static void
- gtk_update_area(struct updateblock *ptr, int num)
- {
- int width = 8;
- static int video_updating;
- RECT updaterect, rect;
- u8 *scrn;
- int i,j;
- int offs;
-
- drawpixelsfunc func;
- GdkGC *gc;
-
- if (video_updating)
- return;
-
- video_updating = 1;
-
- if (GTK_x_mult >= 1 && GTK_x_mult <= 4)
- func = drawpixels_NxN[GTK_x_mult-1][gdkimage->bpp-1];
- else
- func = drawpixels_XxY[gdkimage->bpp-1];
-
- gc = gdk_gc_new(v9t9_drawing_area->window);
-
- if (!gdkimage || !gdkimage->mem)
- return;
-
- SetRectEmpty(&updaterect);
-
- offs=(GTK_x_size/2)-128;
- while (num--)
- {
- scrn = (u8*)gdkimage->mem +
- (ptr->r * GTK_y_mult * gdkimage->bpl) +
- (ptr->c + offs) * GTK_x_mult * gdkimage->bpp;
-
- for (i = 0; i < 8; i++) {
- for (j = 0; j < GTK_y_mult; j++) {
- func(scrn, ptr->data, width);
- scrn += gdkimage->bpl;
- }
- ptr->data += UPDATEBLOCK_ROW_STRIDE;
- }
-
- SetRect(&rect, ptr->c, ptr->r, ptr->c + width, ptr->r + 8);
- UnionRect(&updaterect, &updaterect, &rect);
- ptr++;
- }
-
- gdk_draw_image(v9t9_drawing_area->window,
- gc,
- gdkimage,
- updaterect.left, updaterect.top,
- (updaterect.left + offs) * GTK_x_mult, updaterect.top * GTK_y_mult,
- (updaterect.right - updaterect.left) * GTK_x_mult,
- (updaterect.bottom - updaterect.top) * GTK_y_mult);
-
- gdk_gc_unref(gc);
-
- video_updating = 0;
- }
-
- #elif 0
-
- static void
- gtk_update_area(struct updateblock *ptr, int num)
- {
- int width = 8;
- RECT updaterect, physrect, rect;
- u8 *scrn;
- PAINTSTRUCT pstruct;
- HDC hdc;
- int i,j;
- int offs;
-
- GdkGC *gc = gdk_gc_new(v9t9_drawing_area->window);
-
- if (!gdkimage || !gdkimage->mem)
- return;
-
- SetRectEmpty(&updaterect);
-
- offs=(GTK_x_size/2)-128;
- while (num--)
- {
- // scrn = gdkimage->mem +
- // ((ptr->r * 256) + ptr->c + offs) * gdkimage->bpp;
- for (i=0; i<8; i++)
- {
- for (j=0; j<width; j++)
- gdk_image_put_pixel(gdkimage, ptr->c+j, ptr->r+i,
- v9t9_gdk_palette[ptr->data[j]].pixel);
- // memcpy(scrn,ptr->data,8);
- ptr->data+=UPDATEBLOCK_ROW_STRIDE;
- // scrn += 256;
- }
-
- SetRect(&rect, ptr->c, ptr->r, ptr->c + width, ptr->r + 8);
- //window_invalidate(&rect);
- UnionRect(&updaterect, &updaterect, &rect);
- ptr++;
- }
-
- gdk_draw_image(v9t9_drawing_area->window,
- gc,
- gdkimage,
- updaterect.left, updaterect.top,
- updaterect.left + offs * GTK_x_mult, updaterect.top,
- updaterect.right - updaterect.left,
- updaterect.bottom - updaterect.top);
-
- gdk_gc_unref(gc);
- }
- #elif 0
-
- static void
- gtk_update_area(struct updateblock *ptr, int num)
- {
- int width = 8;
- u8 *blk;
- RECT points[17][64], *pptr[17], *iter;
- int rects = 0, pixels = 0;
- int xoffs = (256 - GTK_x_size) / 2;
-
- HDC hdc = GetDC((HWND)GDK_WINDOW_XWINDOW((GdkWindowPrivate *)(v9t9_drawing_area->window)));
-
- while (num--) {
- int i;
- int j;
- u8 c;
- int d;
-
- ptr->r *= GTK_y_mult;
- ptr->c = (ptr->c + xoffs) * GTK_x_mult;
-
- /* Reset lists for each color (remember text mode has color==16) */
- for (c = 0; c < 17; c++)
- pptr[c] = points[c];
-
- /* Generate a list of rectangles for each color
- in the 8x8 block */
- for (i = 0; i < 8; i++) {
- j = 0;
- while (j < width) {
- /* Find the longest run of pixels of this color */
- c = ptr->data[j];
- d = 1;
- while (j + d < width && ptr->data[j + d] == c)
- d++;
-
- pptr[c]->left = ptr->c + j * GTK_x_mult;
- pptr[c]->top = ptr->r + i * GTK_y_mult;
- pptr[c]->right = GTK_x_mult * d;
- pptr[c]->bottom = GTK_y_mult;
-
- rects++;
- pixels += pptr[c]->right * pptr[c]->bottom;
-
- pptr[c]++;
- j += d;
- }
- ptr->data += UPDATEBLOCK_ROW_STRIDE;
- }
-
- for (c = 0; c <= 16; c++) {
- if (pptr[c] > points[c] && v9t9_gdk_colors[cmap[c]]) {
- iter = points[c];
- while (iter < pptr[c]) {
- gdk_draw_rectangle(v9t9_drawing_area->window,
- v9t9_gdk_colors[cmap[c]],
- TRUE /* filled */,
- iter->left,
- iter->top,
- iter->right,
- iter->bottom);
- iter++;
- }
- }
- }
-
- ptr++;
- }
-
- ReleaseDC((HWND)GDK_WINDOW_XWINDOW((GdkWindowPrivate *)(v9t9_drawing_area->window)), hdc);
-
- // XFlush(GDK_WINDOW_XDISPLAY(v9t9_drawing_area->window));
- logger(_L | L_2, "Drew %d rects, %d pixels\n", rects, pixels);
-
- // g_free(gc);
- }
- #endif
-
-
- #if 0
- #pragma mark -
- #endif
-
- /*****************/
-
- #if defined(UNDER_UNIX)
-
-
- #elif defined(UNDER_WIN32)
-
- #endif
-
- static vmResult
- gtkvideo_updatelist(struct updateblock *ptr, int num)
- {
- gtk_update_area(ptr, num);
- return vmOk;
- }
-
- void GTK_clear_sides(int total, int inside)
- {
- if (inside < total && v9t9_gdk_colors[vdpbg])
- {
- int strip = (total - inside) * GTK_x_mult / 2;
-
- // clear sides
- gdk_draw_rectangle(v9t9_drawing_area->window, v9t9_gdk_colors[vdpbg], 1,
- 0, 0,
- strip, GTK_y_size * GTK_y_mult);
- gdk_draw_rectangle(v9t9_drawing_area->window, v9t9_gdk_colors[vdpbg], 1,
- total * GTK_x_mult - strip, 0,
- strip, GTK_y_size * GTK_y_mult);
- }
- }
-
- static vmResult
- gtkvideo_resize(u32 newxsize, u32 newysize)
- {
- GTK_clear_sides(GTK_x_size, newxsize);
- GTK_x_size = newxsize;
- GTK_y_size = newysize;
- gtk_widget_queue_resize(v9t9_window);
- return vmOk;
- }
-
- static vmResult
- gtkvideo_setfgbg(u8 fg, u8 bg)
- {
- video_setpaletteentry(0, bg);
- video_setpaletteentry(16, fg);
- if (!v9t9_gdk_paletted) {
- GTK_clear_sides(256, GTK_x_size);
- vdpcompleteredraw();
- }
- return vmOk;
- }
-
- static vmResult
- gtkvideo_setblank(u8 bg)
- {
- int x;
-
- for (x = 0; x <= 16; x++)
- video_setpaletteentry(x, bg);
- if (!v9t9_gdk_paletted) {
- // GTK_clear_sides(256, GTK_x_size);
- vdpcompleteredraw();
- }
- return vmOk;
- }
-
- static vmResult
- gtkvideo_resetfromblank(void)
- {
- video_updatepalette();
- if (!v9t9_gdk_paletted) {
- // GTK_clear_sides(256, GTK_x_size);
- vdpcompleteredraw();
- }
- return vmOk;
- }
-
- /***********************************************************/
-
- static vmVideoModule gtkvideo_videoModule = {
- 3,
- gtkvideo_updatelist,
- gtkvideo_resize,
- gtkvideo_setfgbg,
- gtkvideo_setblank,
- gtkvideo_resetfromblank
- };
-
- vmModule gtkVideo = {
- 3,
- "GTK+ video",
- "vidGTK",
-
- vmTypeVideo,
- vmFlagsExclusive,
-
- gtkvideo_detect,
- gtkvideo_init,
- gtkvideo_term,
- gtkvideo_enable,
- gtkvideo_disable,
- gtkvideo_restart,
- gtkvideo_restop,
- {(vmGenericModule *) & gtkvideo_videoModule}
- };
-