-// NOTE TTimo window position saving has always been tricky
-// it doesn't work the same between win32 and linux .. see below that code is fairly different
-// it's also very poorly done, the save calls are a bit randomly disctributed in the OnDestroy
-
-void save_window_pos (GtkWidget *wnd, window_position_t& pos)
-{
- if ((wnd == NULL) || (wnd->window == NULL))
- return;
-
- get_window_pos(wnd, &pos.x, &pos.y);
-
- pos.w = wnd->allocation.width;
- pos.h = wnd->allocation.height;
-
-#ifdef DBG_WINDOWPOS
- //Sys_Printf("save_window_pos 'Window %s'\n",buf);
-#endif
-}
-
-#ifdef _WIN32
-void win32_get_window_pos(GtkWidget *widget, gint *x, gint *y)
-{
- // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=913
- if ( g_PrefsDlg.m_bStartOnPrimMon ) {
- RECT rc;
- POINT point;
- HWND xwnd = (HWND)GDK_WINDOW_HWND (widget->window);
- const GdkRectangle primaryMonitorRect = g_pParentWnd->GetPrimaryMonitorRect();
-
- GetClientRect(xwnd,&rc);
- point.x=rc.left;
- point.y=rc.top;
- ClientToScreen(xwnd,&point);
-
- *x=point.x;
- *y=point.y;
-
- *x=max(*x,-widget->allocation.width+10);
- *x=min(*x,primaryMonitorRect.width-10);
- *y=max(*y,-widget->allocation.height+10);
- *y=min(*y,primaryMonitorRect.height-10);
- } else {
- // this is the same as the unix version of get_window_pos
- gdk_window_get_root_origin (widget->window, x, y);
- }
-#ifdef DBG_WINDOWPOS
- Sys_Printf("win32_get_window_pos %p %d,%d\n",widget,*x,*y);
-#endif
-}
-#endif
-
-void load_window_pos (GtkWidget *wnd, window_position_t& pos)
-{
-#ifdef _WIN32
- const GdkRectangle primaryMonitorRect = g_pParentWnd->GetPrimaryMonitorRect();
-
- if(pos.x < primaryMonitorRect.x
- || pos.y < primaryMonitorRect.y
- || pos.x > primaryMonitorRect.x + primaryMonitorRect.width
- || pos.y > primaryMonitorRect.y + primaryMonitorRect.height)
- gtk_window_set_position(GTK_WINDOW(wnd), GTK_WIN_POS_CENTER_ON_PARENT);
-#else
- // FIXME: not multihead safe
- if(pos.x < 0
- || pos.y < 0
- || pos.x > gdk_screen_width ()
- || pos.y > gdk_screen_height ())
- gtk_window_set_position(GTK_WINDOW(wnd), GTK_WIN_POS_CENTER_ON_PARENT);
-#endif
- else
- gtk_window_move(GTK_WINDOW(wnd), pos.x, pos.y);
-
- gtk_window_set_default_size (GTK_WINDOW (wnd), pos.w, pos.h);
-#ifdef DBG_WINDOWPOS
- Sys_Printf("load_window_pos %p 'Window,%s'\n",wnd,windowData);
-#endif
-}
-
-gint widget_delete_hide (GtkWidget *widget)
-{
- gtk_widget_hide (widget);
-
- return TRUE;
-}
-
-
-// Thanks to Mercury, Fingolfin - ETG
-int readLongLE(FILE *file, unsigned long *m_bytesRead, int *value)
-{
- byte buf[4];
- int len = fread(buf, 4, 1, file);
- *m_bytesRead += 4;
- if (len != 1)
- return -1;
-
- *value = buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24;
- return 0;
-}
-
-short readShortLE(FILE *file, unsigned long *m_bytesRead, short unsigned *value)
-{
- byte buf[2];
- int len = fread(buf, 2, 1, file);
- *m_bytesRead += 2;
- if (len != 1)
- return -1;
-
- *value = buf[0] | buf[1] << 8;
- return 0;
-}
-
-unsigned char *load_bitmap_file (const char* filename, guint16 *width, guint16 *height)
-{
- int bmWidth, bmHeight;
- short unsigned bmPlanes, bmBitsPixel;
- typedef struct {
- unsigned char rgbBlue;
- unsigned char rgbGreen;
- unsigned char rgbRed;
- unsigned char rgbReserved;
- } RGBQUAD;
- unsigned char m1,m2;
- int sizeimage;
- short unsigned res1,res2;
- int filesize, pixoff;
- int bmisize, compression;
- int xscale, yscale;
- int colors, impcol;
- unsigned long m_bytesRead = 0;
- unsigned char *imagebits = NULL;
- FILE *fp;
-
- *width = *height = 0;
-
- fp = fopen(filename,"rb");
- if (fp == NULL)
- {
- return NULL;
- }
-
- size_t rc;
- rc = fread(&m1, 1, 1, fp);
- m_bytesRead++;
- if (rc == -1)
- {
- fclose(fp);
- return NULL;
- }
-
- rc = fread(&m2, 1, 1, fp);
- m_bytesRead++;
- if ((m1!='B') || (m2!='M'))
- {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&filesize)) {
- fclose(fp);
- return NULL;
- }
-
- if (readShortLE(fp,&m_bytesRead,&res1)) {
- fclose(fp);
- return NULL;
- }
-
- if (readShortLE(fp,&m_bytesRead,&res2)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&pixoff)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&bmisize)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&bmWidth)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&bmHeight)) {
- fclose(fp);
- return NULL;
- }
-
- if (readShortLE(fp,&m_bytesRead,&bmPlanes)) {
- fclose(fp);
- return NULL;
- }
-
- if (readShortLE(fp,&m_bytesRead,&bmBitsPixel)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&compression)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&sizeimage)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&xscale)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&yscale)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&colors)) {
- fclose(fp);
- return NULL;
- }
-
- if (readLongLE(fp,&m_bytesRead,&impcol)) {
- fclose(fp);
- return NULL;
- }
-
- if (colors == 0)
- colors = 1 << bmBitsPixel;
-
- RGBQUAD *colormap = NULL;
- if (bmBitsPixel != 24)
- {
- colormap = new RGBQUAD[colors];
- if (colormap == NULL)
- {
- fclose(fp);
- return NULL;
- }
-
- int i;
- for (i = 0; i < colors; i++)
- {
- unsigned char r ,g, b, dummy;
-
- rc = fread(&b, 1, 1, fp);
- m_bytesRead++;
- if (rc!=1)
- {
- delete [] colormap;
- fclose(fp);
- return NULL;
- }
-
- rc = fread(&g, 1, 1, fp);
- m_bytesRead++;
- if (rc!=1)
- {
- delete [] colormap;
- fclose(fp);
- return NULL;
- }
-
- rc = fread(&r, 1, 1, fp);
- m_bytesRead++;
- if (rc != 1)
- {
- delete [] colormap;
- fclose(fp);
- return NULL;
- }
-
- rc = fread(&dummy, 1, 1, fp);
- m_bytesRead++;
- if (rc != 1)
- {
- delete [] colormap;
- fclose(fp);
- return NULL;
- }
-
- colormap[i].rgbRed=r;
- colormap[i].rgbGreen=g;
- colormap[i].rgbBlue=b;
- }
- }
-
- if ((long)m_bytesRead > pixoff)
- {
- delete [] colormap;
- fclose(fp);
- return NULL;
- }
-
- while ((long)m_bytesRead < pixoff)
- {
- char dummy;
- fread(&dummy,1,1,fp);
- m_bytesRead++;
- }
-
- int w = bmWidth;
- int h = bmHeight;
-
- // set the output params
- imagebits = (unsigned char *)malloc(w * h * 3);
- long row_size = w * 3;
-
- if (imagebits != NULL)
- {
- *width = w;
- *height = h;
- unsigned char *outbuf = imagebits;
- long row = 0;
- long rowOffset = 0;
-
- if (compression == 0) // BI_RGB
- {
- // read rows in reverse order
- for (row = bmHeight - 1; row >= 0; row--)
- {
- // which row are we working on?
- rowOffset = (long unsigned)row * row_size;
-
- if (bmBitsPixel == 24)
- {
- for (int col=0;col<w;col++)
- {
- long offset = col * 3;
- char pixel[3];
-
- if (fread((void *)(pixel),1,3,fp) == 3)
- {
- // we swap red and blue here
- *(outbuf + rowOffset + offset + 0) = pixel[2]; // r
- *(outbuf + rowOffset + offset + 1) = pixel[1]; // g
- *(outbuf + rowOffset + offset + 2) = pixel[0]; // b
- }
- }
- m_bytesRead += row_size;
-
- // read DWORD padding
- while ((m_bytesRead - pixoff) & 3)
- {
- char dummy;
- if (fread(&dummy,1,1,fp) != 1)
- {
- free(imagebits);
- fclose(fp);
- return NULL;
- }
- m_bytesRead++;
- }
- }
- else
- {
- // pixels are packed as 1 , 4 or 8 bit vals. need to unpack them
- int bit_count = 0;
- unsigned long mask = (1 << bmBitsPixel) - 1;
- unsigned char inbyte = 0;
-
- for (int col = 0; col < w; col++)
- {
- int pix = 0;
-
- // if we need another byte
- if (bit_count <= 0)
- {
- bit_count = 8;
- if (fread(&inbyte,1,1,fp) != 1)
- {
- free(imagebits);
- delete [] colormap;
- fclose(fp);
- return NULL;
- }
- m_bytesRead++;
- }
-
- // keep track of where we are in the bytes
- bit_count -= bmBitsPixel;
- pix = ( inbyte >> bit_count) & mask;
-
- // lookup the color from the colormap - stuff it in our buffer
- // swap red and blue
- *(outbuf + rowOffset + col * 3 + 2) = colormap[pix].rgbBlue;
- *(outbuf + rowOffset + col * 3 + 1) = colormap[pix].rgbGreen;
- *(outbuf + rowOffset + col * 3 + 0) = colormap[pix].rgbRed;
- }
-
- // read DWORD padding
- while ((m_bytesRead - pixoff) & 3)
- {
- char dummy;
- if (fread(&dummy,1,1,fp)!=1)
- {
- free(imagebits);
- if (colormap)
- delete [] colormap;
- fclose(fp);
- return NULL;
- }
- m_bytesRead++;
- }
- }
- }
- }
- else
- {
- int i, x = 0;
- unsigned char c, c1 = 0, *pp;
- row = 0;
- pp = outbuf + (bmHeight - 1) * bmWidth * 3;
-
- if (bmBitsPixel == 8)
- {
- while (row < bmHeight)
- {
- c = getc(fp);
-
- if (c)
- {
- // encoded mode
- c1 = getc(fp);
- for (i = 0; i < c; x++, i++)
- {
- *pp = colormap[c1].rgbRed; pp++;
- *pp = colormap[c1].rgbGreen; pp++;
- *pp = colormap[c1].rgbBlue; pp++;
- }
- }
- else
- {
- // c==0x00, escape codes
- c = getc(fp);
- if (c == 0x00) // end of line
- {
- row++;
- x = 0;
- pp = outbuf + (bmHeight - row - 1) * bmWidth * 3;
- }
- else if (c == 0x01)
- break; // end of pic
- else if (c == 0x02) // delta
- {
- c = getc(fp);
- x += c;
- c = getc(fp);
- row += c;
- pp = outbuf + x*3 + (bmHeight - row - 1) * bmWidth * 3;
- }
- else // absolute mode
- {
- for (i = 0; i < c; x++, i++)
- {
- c1 = getc(fp);
- *pp = colormap[c1].rgbRed; pp++;
- *pp = colormap[c1].rgbGreen; pp++;
- *pp = colormap[c1].rgbBlue; pp++;
- }
-
- if (c & 1)
- getc(fp); // odd length run: read an extra pad byte
- }
- }
- }
- }
- else if (bmBitsPixel == 4)
- {
- while (row < bmHeight)
- {
- c = getc(fp);
-
- if (c)
- {
- // encoded mode
- c1 = getc(fp);
- for (i = 0; i < c; x++, i++)
- {
- *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbRed; pp++;
- *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbGreen; pp++;
- *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbBlue; pp++;
- }
- }
- else
- {
- // c==0x00, escape codes
- c = getc(fp);
-
- if (c == 0x00) // end of line
- {
- row++;
- x = 0;
- pp = outbuf + (bmHeight - row - 1) * bmWidth * 3;
- }
- else if (c == 0x01)
- break; // end of pic
- else if (c == 0x02) // delta
- {
- c = getc(fp);
- x += c;
- c = getc(fp);
- row += c;
- pp = outbuf + x * 3 + (bmHeight - row - 1) * bmWidth * 3;
- }
- else // absolute mode
- {
- for (i = 0; i < c; x++, i++)
- {
- if ((i&1) == 0)
- c1 = getc(fp);
- *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbRed; pp++;
- *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbGreen; pp++;
- *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbBlue; pp++;
- }
-
- if (((c & 3) == 1) || ((c & 3) == 2))
- getc(fp); // odd length run: read an extra pad byte
- }
- }
- }
- }
- }
- if (colormap)
- delete [] colormap;
-
- fclose(fp);
- }
- return imagebits;
-}
-
-void bmp_to_pixmap (const char* filename, GdkPixmap **pixmap, GdkBitmap **mask)
-{
- guint16 width, height;
- unsigned char *buf;
- GdkWindow *window = gdk_get_default_root_window();
- GdkColormap *colormap;
- GdkGC* gc = gdk_gc_new (window);
- int i, j;
- bool hasMask = false;
-
- *pixmap = *mask = NULL;
- buf = load_bitmap_file (filename, &width, &height);
- if (!buf)
- return;
-
- colormap = gdk_drawable_get_colormap (window);
- *pixmap = gdk_pixmap_new (window, width, height, -1);
-
- typedef struct
- {
- GdkColor c;
- unsigned char *p;
- } PAL;
-
- for (i = 0; i < height; i++)
- {
- for (j = 0; j < width; j++)
- {
- unsigned char *p = &buf[(i * width + j) * 3];
- PAL pe;
-
- pe.c.red = (gushort)(p[0] * 0xFF);
- pe.c.green = (gushort)(p[1] * 0xFF);
- pe.c.blue = (gushort)(p[2] * 0xFF);
- gdk_colormap_alloc_color(colormap, &pe.c, FALSE, TRUE);
- gdk_gc_set_foreground(gc, &pe.c);
- gdk_draw_point(*pixmap, gc, j, i);
-
- if (p[0] == 0xFF && p[1] == 0x00 && p[2] == 0xFF)
- hasMask = true;
- }
- }
-
- gdk_gc_unref (gc);
- *mask = gdk_pixmap_new (window, width, height, 1);
- gc = gdk_gc_new (*mask);
- if (hasMask)
- {
- for (i = 0; i < height; i++)
- {
- for (j = 0; j < width; j++)
- {
- GdkColor mask_pattern;
-
- // pink is transparent
- if ((buf[(i*width+j)*3] == 0xff) &&
- (buf[(i*width+j)*3+1] == 0x00) &&
- (buf[(i*width+j)*3+2] == 0xff))
- mask_pattern.pixel = 0;
- else
- mask_pattern.pixel = 1;
-
- gdk_gc_set_foreground (gc, &mask_pattern);
- // possible Win32 Gtk bug here
- //gdk_draw_point (*mask, gc, j, i);
- gdk_draw_line (*mask, gc, j, i, j + 1, i);
- }
- }
- }
- else
- {
- GdkColor mask_pattern;
- mask_pattern.pixel = 1;
- gdk_gc_set_foreground (gc, &mask_pattern);
- gdk_draw_rectangle (*mask, gc, 1, 0, 0, width, height);
- }
- gdk_gc_unref(gc);
- free (buf);
-}
-
-void load_pixmap (const char* filename, GtkWidget* widget, GdkPixmap **gdkpixmap, GdkBitmap **mask)
-{
- CString str;
-
- str = g_strBitmapsPath;
- str += filename;
-
- bmp_to_pixmap (str.GetBuffer (), gdkpixmap, mask);
- if (*gdkpixmap == NULL)
- {
- printf("gdkpixmap was null\n");
- gchar *dummy[] = { "1 1 1 1", " c None", " " };
- printf("calling gdk_pixmap_create_from_xpm_d\n");
- *gdkpixmap = gdk_pixmap_create_from_xpm_d (gdk_get_default_root_window(), mask, NULL, dummy);
- }
-}
-
-// this is the same as above but used by the plugins
-// GdkPixmap **gdkpixmap, GdkBitmap **mask
-bool WINAPI load_plugin_bitmap (const char* filename, void **gdkpixmap, void **mask)
-{
- CString str;
-
- str = g_strGameToolsPath;
- str += g_strPluginsDir;
- str += "bitmaps/";
- str += filename;
- bmp_to_pixmap (str.GetBuffer (), (GdkPixmap **)gdkpixmap, (GdkBitmap **)mask);
-
- if (*gdkpixmap == NULL)
- {
- // look in the core plugins
- str = g_strAppPath;
- str += g_strPluginsDir;
- str += "bitmaps/";
- str += filename;
- bmp_to_pixmap (str.GetBuffer (), (GdkPixmap **)gdkpixmap, (GdkBitmap **)mask);
-
- if (*gdkpixmap == NULL)
- {
-
- // look in core modules
- str = g_strAppPath;
- str += g_strModulesDir;
- str += "bitmaps/";
- str += filename;
- bmp_to_pixmap (str.GetBuffer (), (GdkPixmap **)gdkpixmap, (GdkBitmap **)mask);
-
- if (*gdkpixmap == NULL)
- {
- gchar *dummy[] = { "1 1 1 1", " c None", " " };
- *gdkpixmap = gdk_pixmap_create_from_xpm_d (gdk_get_default_root_window(), (GdkBitmap **)mask, NULL, dummy);
- return false;
- }
- }
- }
- return true;
-}
-
-// Load a xpm file and return a pixmap widget.
-GtkWidget* new_pixmap (GtkWidget* widget, const char* filename)
-{
- GdkPixmap *gdkpixmap;
- GdkBitmap *mask;
- GtkWidget *pixmap;
-
- load_pixmap (filename, widget, &gdkpixmap, &mask);
- pixmap = gtk_pixmap_new (gdkpixmap, mask);
-
- gdk_drawable_unref (gdkpixmap);
- gdk_drawable_unref (mask);
-
- return pixmap;
-}
-
-// =============================================================================
-// Menu stuff
-
-GtkWidget* menu_separator (GtkWidget *menu)
-{
- GtkWidget *menu_item = gtk_menu_item_new ();
- gtk_menu_append (GTK_MENU (menu), menu_item);
- gtk_widget_set_sensitive (menu_item, FALSE);
- gtk_widget_show (menu_item);
- return menu_item;
-}
-
-GtkWidget* menu_tearoff (GtkWidget *menu)
-{
- GtkWidget *menu_item = gtk_tearoff_menu_item_new ();
- gtk_menu_append (GTK_MENU (menu), menu_item);
-// gtk_widget_set_sensitive (menu_item, FALSE); -- controls whether menu is detachable
- gtk_widget_show (menu_item);
- return menu_item;
-}
-
-GtkWidget* create_sub_menu_with_mnemonic (GtkWidget *bar, const gchar *mnemonic)