-// 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 ){
- 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 ){
- GtkWidget *item, *sub_menu;
-
- item = gtk_menu_item_new_with_mnemonic( mnemonic );
- gtk_widget_show( item );
- gtk_container_add( GTK_CONTAINER( bar ), item );
-
- sub_menu = gtk_menu_new();
- gtk_menu_item_set_submenu( GTK_MENU_ITEM( item ), sub_menu );
-
- return sub_menu;
-}
-
-extern void AddMenuItem( GtkWidget* menu, unsigned int id );
-
-GtkWidget* create_menu_item_with_mnemonic( GtkWidget *menu, const gchar *mnemonic, GtkSignalFunc func, int id ){
- GtkWidget *item;
-
- item = gtk_menu_item_new_with_mnemonic( mnemonic );
-
- gtk_widget_show( item );
- gtk_container_add( GTK_CONTAINER( menu ), item );
- gtk_signal_connect( GTK_OBJECT( item ), "activate", GTK_SIGNAL_FUNC( func ), GINT_TO_POINTER( id ) );
-
- AddMenuItem( item, id );
- return item;