X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fglyphs-msw.c;h=72902aa3ea00d669311306feb43284b66251cce5;hb=a858680c386500889ac6f2d6d47f392c8a743c01;hp=00506b566fb76f2ef28c6372ee6396c07203d811;hpb=46f51e794ddb493a8a76ec2f3be00b41e3b0be22;p=chise%2Fxemacs-chise.git.1 diff --git a/src/glyphs-msw.c b/src/glyphs-msw.c index 00506b5..72902aa 100644 --- a/src/glyphs-msw.c +++ b/src/glyphs-msw.c @@ -1,5 +1,5 @@ /* mswindows-specific glyph objects. - Copyright (C) 1998, 1999 Andy Piper. + Copyright (C) 1998, 1999, 2000 Andy Piper. This file is part of XEmacs. @@ -20,7 +20,7 @@ Boston, MA 02111-1307, USA. */ /* Synched up with: Not in FSF. */ -/* written by Andy Piper plagerising bits from +/* written by Andy Piper plagiarising bits from glyphs-x.c */ #include @@ -57,7 +57,6 @@ DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing); DECLARE_IMAGE_INSTANTIATOR_FORMAT (string); DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit); -DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout); #ifdef HAVE_JPEG DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg); #endif @@ -72,11 +71,16 @@ DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif); #endif #ifdef HAVE_XPM DEFINE_DEVICE_IIFORMAT (mswindows, xpm); +DEFINE_DEVICE_IIFORMAT (msprinter, xpm); #endif DEFINE_DEVICE_IIFORMAT (mswindows, xbm); +DEFINE_DEVICE_IIFORMAT (msprinter, xbm); #ifdef HAVE_XFACE DEFINE_DEVICE_IIFORMAT (mswindows, xface); +DEFINE_DEVICE_IIFORMAT (msprinter, xface); #endif +DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout); +DEFINE_DEVICE_IIFORMAT (mswindows, native_layout); DEFINE_DEVICE_IIFORMAT (mswindows, button); DEFINE_DEVICE_IIFORMAT (mswindows, edit_field); DEFINE_DEVICE_IIFORMAT (mswindows, subwindow); @@ -98,14 +102,60 @@ Lisp_Object Q_resource_type, Q_resource_id; Lisp_Object Qmswindows_resource; static void -mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, +mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii, int slices, enum image_instance_type type); static void -mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, - struct frame* f); +mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image, + HDC hcdc); + +/* + * Given device D, retrieve compatible device context. D can be either + * mswindows or an msprinter device. + */ +inline static HDC +get_device_compdc (struct device *d) +{ + if (DEVICE_MSWINDOWS_P (d)) + return DEVICE_MSWINDOWS_HCDC (d); + else + return DEVICE_MSPRINTER_HCDC (d); +} -COLORREF mswindows_string_to_color (CONST char *name); +/* + * Initialize image instance pixel sizes in II. For a display bitmap, + * these will be same as real bitmap sizes. For a printer bitmap, + * these will be scaled up so that the bitmap is proportionally enlarged + * when output to printer. Redisplay code takes care of scaling, to + * conserve memory we do not really scale bitmaps. Set the watermark + * only here. + * #### Add support for unscalable bitmaps. + */ +static void init_image_instance_geometry (Lisp_Image_Instance *ii) +{ + struct device *d = DOMAIN_XDEVICE (ii->domain); + + if (/* #### Scaleable && */ DEVICE_MSPRINTER_P (d)) + { + HDC printer_dc = DEVICE_MSPRINTER_HCDC (d); + HDC display_dc = CreateCompatibleDC (NULL); + IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = + MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii), + GetDeviceCaps (printer_dc, LOGPIXELSX), + GetDeviceCaps (display_dc, LOGPIXELSX)); + IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = + MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii), + GetDeviceCaps (printer_dc, LOGPIXELSY), + GetDeviceCaps (display_dc, LOGPIXELSY)); + } + else + { + IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = + IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii); + IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = + IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii); + } +} #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3))) @@ -126,7 +176,7 @@ static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device, BITMAPINFO* bmp_info; unsigned char *ip, *dp; - if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0) + if (GetDeviceCaps (get_device_compdc (d), BITSPIXEL) > 0) { int bpline = BPLINE(width * 3); /* FIXME: we can do this because 24bpp implies no color table, once @@ -208,25 +258,28 @@ static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device, } /* build up an RGBQUAD colortable */ - for (i = 0; i < qtable->num_active_colors; i++) { - colortbl[i].rgbRed = (BYTE) qtable->rm[i]; - colortbl[i].rgbGreen = (BYTE) qtable->gm[i]; - colortbl[i].rgbBlue = (BYTE) qtable->bm[i]; - colortbl[i].rgbReserved = 0; - } + for (i = 0; i < qtable->num_active_colors; i++) + { + colortbl[i].rgbRed = (BYTE) qtable->rm[i]; + colortbl[i].rgbGreen = (BYTE) qtable->gm[i]; + colortbl[i].rgbBlue = (BYTE) qtable->bm[i]; + colortbl[i].rgbReserved = 0; + } /* now build up the data. picture has to be upside-down and back-to-front for msw bitmaps */ ip = pic; - for (i = height-1; i >= 0; i--) { - dp = (*bmp_data) + (i * bpline); - for (j = 0; j < width; j++) { - rd = *ip++; - gr = *ip++; - bl = *ip++; - *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl); + for (i = height-1; i >= 0; i--) + { + dp = (*bmp_data) + (i * bpline); + for (j = 0; j < width; j++) + { + rd = *ip++; + gr = *ip++; + bl = *ip++; + *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl); + } } - } xfree (qtable); } /* fix up the standard stuff */ @@ -259,7 +312,7 @@ mswindows_locate_pixmap_file (Lisp_Object name) (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2))))))) { if (!NILP (Ffile_readable_p (name))) - return name; + return Fexpand_file_name (name, Qnil); else return Qnil; } @@ -286,7 +339,7 @@ mswindows_locate_pixmap_file (Lisp_Object name) in the error message. */ static void -init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, +init_image_instance_from_dibitmap (Lisp_Image_Instance *ii, BITMAPINFO *bmp_info, int dest_mask, void *bmp_data, @@ -296,22 +349,12 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, int x_hot, int y_hot, int create_mask) { - Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - struct device *d = XDEVICE (device); - struct frame *f; + struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii)); void* bmp_buf=0; - int type = 0; + enum image_instance_type type; HBITMAP bitmap; HDC hdc; - if (!DEVICE_MSWINDOWS_P (d)) - signal_simple_error ("Not an mswindows device", device); - - if (NILP (DEVICE_SELECTED_FRAME (d))) - signal_simple_error ("No selected frame on mswindows device", device); - - f = XFRAME (DEVICE_SELECTED_FRAME (d)); - if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) type = IMAGE_COLOR_PIXMAP; else if (dest_mask & IMAGE_POINTER_MASK) @@ -319,13 +362,13 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, else incompatible_image_types (instantiator, dest_mask, IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); - hdc = FRAME_MSWINDOWS_CDC (f); - bitmap=CreateDIBSection (hdc, - bmp_info, - DIB_RGB_COLORS, - &bmp_buf, - 0,0); + hdc = get_device_compdc (d); + bitmap = CreateDIBSection (hdc, + bmp_info, + DIB_RGB_COLORS, + &bmp_buf, + 0, 0); if (!bitmap || !bmp_buf) signal_simple_error ("Unable to create bitmap", instantiator); @@ -342,15 +385,18 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap; IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL; - IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth; - IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight; - IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount; + IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = + bmp_info->bmiHeader.biWidth; + IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = + bmp_info->bmiHeader.biHeight; + IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount; XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot); XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot); + init_image_instance_geometry (ii); if (create_mask) { - mswindows_initialize_image_instance_mask (ii, f); + mswindows_initialize_image_instance_mask (ii, hdc); } if (type == IMAGE_POINTER) @@ -360,19 +406,17 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, } static void -image_instance_add_dibitmap (struct Lisp_Image_Instance *ii, +image_instance_add_dibitmap (Lisp_Image_Instance *ii, BITMAPINFO *bmp_info, void *bmp_data, int bmp_bits, int slice, Lisp_Object instantiator) { - Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - struct device *d = XDEVICE (device); - struct frame *f = XFRAME (DEVICE_SELECTED_FRAME (d)); + struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii)); void* bmp_buf=0; - HDC hdc = FRAME_MSWINDOWS_CDC (f); - HBITMAP bitmap = CreateDIBSection (hdc, + + HBITMAP bitmap = CreateDIBSection (get_device_compdc (d), bmp_info, DIB_RGB_COLORS, &bmp_buf, @@ -387,7 +431,7 @@ image_instance_add_dibitmap (struct Lisp_Image_Instance *ii, } static void -mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, +mswindows_init_image_instance_from_eimage (Lisp_Image_Instance *ii, int width, int height, int slices, unsigned char *eimage, @@ -402,8 +446,7 @@ mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, COLORREF bkcolor; int slice; - if (!DEVICE_MSWINDOWS_P (XDEVICE (device))) - signal_simple_error ("Not an mswindows device", device); + CHECK_MSGDI_DEVICE (device); /* this is a hack but MaskBlt and TransparentBlt are not supported on most windows variants */ @@ -435,50 +478,49 @@ mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, } } -static void set_mono_pixel ( unsigned char* bits, - int bpline, int height, - int x, int y, int white ) +inline static void +set_mono_pixel (unsigned char* bits, + int bpline, int height, + int x, int y, int white) { - int index; - unsigned char bitnum; + int i; + unsigned char bitnum; /* Find the byte on which this scanline begins */ - index = (height - y - 1) * bpline; + i = (height - y - 1) * bpline; /* Find the byte containing this pixel */ - index += (x >> 3); + i += (x >> 3); /* Which bit is it? */ - bitnum = (unsigned char)( 7 - (x % 8) ); - if( white ) /* Turn it on */ - bits[index] |= (1<bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image); + bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image); bmp_info->bmiHeader.biHeight = height; - bmp_info->bmiHeader.biPlanes=1; + bmp_info->bmiHeader.biPlanes = 1; bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); - bmp_info->bmiHeader.biBitCount=1; - bmp_info->bmiHeader.biCompression=BI_RGB; + bmp_info->bmiHeader.biBitCount = 1; + bmp_info->bmiHeader.biCompression = BI_RGB; bmp_info->bmiHeader.biClrUsed = 2; bmp_info->bmiHeader.biClrImportant = 2; bmp_info->bmiHeader.biSizeImage = height * maskbpline; @@ -494,7 +536,7 @@ mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, if (!(mask = CreateDIBSection (hcdc, bmp_info, DIB_RGB_COLORS, - &and_bits, + (void**)&and_bits, 0,0))) { xfree (bmp_info); @@ -505,17 +547,17 @@ mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, /* build up an in-memory set of bits to mess with */ xzero (*bmp_info); - bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image); + bmp_info->bmiHeader.biWidth = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image); bmp_info->bmiHeader.biHeight = -height; - bmp_info->bmiHeader.biPlanes=1; - bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); - bmp_info->bmiHeader.biBitCount=24; - bmp_info->bmiHeader.biCompression=BI_RGB; + bmp_info->bmiHeader.biPlanes = 1; + bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmp_info->bmiHeader.biBitCount = 24; + bmp_info->bmiHeader.biCompression = BI_RGB; bmp_info->bmiHeader.biClrUsed = 0; bmp_info->bmiHeader.biClrImportant = 0; bmp_info->bmiHeader.biSizeImage = height * bpline; - dibits = xmalloc_and_zero (bpline * height); + dibits = (unsigned char*) xmalloc_and_zero (bpline * height); if (GetDIBits (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image), 0, @@ -530,20 +572,20 @@ mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, /* now set the colored bits in the mask and transparent ones to black in the original */ - for(i=0; iname, nm)) return res->resource_id; } while ((++res)->name); @@ -1210,13 +1254,13 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); unsigned int type = 0; HANDLE himage = NULL; LPCTSTR resid=0; HINSTANCE hinst = NULL; ICONINFO iconinfo; - int iitype=0; + enum image_instance_type iitype; char* fname=0; Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); @@ -1228,8 +1272,7 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti xzero (iconinfo); - if (!DEVICE_MSWINDOWS_P (XDEVICE (device))) - signal_simple_error ("Not an mswindows device", device); + CHECK_MSGDI_DEVICE (device); type = resource_symbol_to_type (resource_type); @@ -1245,8 +1288,10 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti if (!NILP (file)) { Extbyte* f=0; - GET_C_STRING_FILENAME_DATA_ALLOCA (file, f); -#ifdef __CYGWIN32__ + TO_EXTERNAL_FORMAT (LISP_STRING, file, + C_STRING_ALLOCA, f, + Qfile_name); +#ifdef CYGWIN CYGWIN_WIN32_PATH (f, fname); #else fname = f; @@ -1262,7 +1307,9 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti type)); if (!resid) - GET_C_STRING_OS_DATA_ALLOCA (resource_id, resid); + TO_EXTERNAL_FORMAT (LISP_STRING, resource_id, + C_STRING_ALLOCA, resid, + Qnative); } } else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id, @@ -1270,12 +1317,32 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti signal_simple_error ("Invalid resource identifier", resource_id); /* load the image */ - if (!(himage = LoadImage (hinst, resid, type, 0, 0, - LR_CREATEDIBSECTION | LR_DEFAULTSIZE | - LR_SHARED | - (!NILP (file) ? LR_LOADFROMFILE : 0)))) + if (xLoadImageA) /* not in NT 3.5 */ + { + if (!(himage = xLoadImageA (hinst, resid, type, 0, 0, + LR_CREATEDIBSECTION | LR_DEFAULTSIZE | + LR_SHARED | + (!NILP (file) ? LR_LOADFROMFILE : 0)))) + signal_simple_error ("Cannot load image", instantiator); + } + else { - signal_simple_error ("Cannot load image", instantiator); + /* Is this correct? I don't really care. */ + switch (type) + { + case IMAGE_BITMAP: + himage = LoadBitmap (hinst, resid); + break; + case IMAGE_CURSOR: + himage = LoadCursor (hinst, resid); + break; + case IMAGE_ICON: + himage = LoadIcon (hinst, resid); + break; + } + + if (!himage) + signal_simple_error ("Cannot load image", instantiator); } if (hinst) @@ -1284,27 +1351,28 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti mswindows_initialize_dibitmap_image_instance (ii, 1, iitype); IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file; - IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = + IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON); - IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = + IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON); IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1; + init_image_instance_geometry (ii); /* hey, we've got an icon type thing so we can reverse engineer the bitmap and mask */ if (type != IMAGE_BITMAP) { - GetIconInfo (himage, &iconinfo); + GetIconInfo ((HICON)himage, &iconinfo); IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor; IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask; XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot); XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot); - IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = himage; + IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = (HICON) himage; } else { IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL; - IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = himage; + IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = (HBITMAP) himage; IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL; XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0); XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0); @@ -1330,15 +1398,6 @@ check_valid_resource_id (Lisp_Object data) signal_simple_error ("invalid resource identifier", data); } -void -check_valid_string_or_int (Lisp_Object data) -{ - if (!INTP (data)) - CHECK_STRING (data); - else - CHECK_INT (data); -} - /********************************************************************** * XBM * **********************************************************************/ @@ -1401,13 +1460,14 @@ in this Software without prior written authorization from the X Consortium. /* shared data for the image read/parse logic */ static short hexTable[256]; /* conversion value */ -static int initialized = FALSE; /* easier to fill in at run time */ +static int hex_initialized = FALSE; /* easier to fill in at run time */ /* * Table index for the hex values. Initialized once, first time. * Used for translation value or delimiter significance lookup. */ -static void initHexTable() +static void +initHexTable (void) { /* * We build the table at run time for several reasons: @@ -1434,13 +1494,14 @@ static void initHexTable() hexTable['}'] = -1; hexTable['\n'] = -1; hexTable['\t'] = -1; - initialized = TRUE; + hex_initialized = TRUE; } /* * read next hex value in the input stream, return -1 if EOF */ -static int NextInt ( FILE *fstream ) +static int +NextInt (FILE *fstream) { int ch; int value = 0; @@ -1475,11 +1536,9 @@ static int NextInt ( FILE *fstream ) * its arguments won't have been touched. This routine should look as much * like the Xlib routine XReadBitmapfile as possible. */ -int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot) - FILE *fstream; /* handle on file */ - unsigned int *width, *height; /* RETURNED */ - unsigned char **datap; /* RETURNED */ - int *x_hot, *y_hot; /* RETURNED */ +int read_bitmap_data (FILE* fstream, unsigned int *width, + unsigned int *height, unsigned char **datap, + int *x_hot, int *y_hot) { unsigned char *data = NULL; /* working variable */ char line[MAX_SIZE]; /* input line from file */ @@ -1498,7 +1557,7 @@ int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot) #define Xmalloc(size) malloc(size) /* first time initialization */ - if (initialized == FALSE) initHexTable(); + if (hex_initialized == FALSE) initHexTable(); /* error cleanup and return macro */ #define RETURN(code) { if (data) free (data); return code; } @@ -1599,7 +1658,7 @@ int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot) } -int read_bitmap_data_from_file (CONST char *filename, unsigned int *width, +int read_bitmap_data_from_file (const char *filename, unsigned int *width, unsigned int *height, unsigned char **datap, int *x_hot, int *y_hot) { @@ -1628,7 +1687,7 @@ static int flip_table[] = padded to a multiple of 16. Scan lines are stored in increasing byte order from left to right, big-endian within a byte. 0 = black, 1 = white. */ -HBITMAP +static HBITMAP xbm_create_bitmap_from_data (HDC hdc, char *data, unsigned int width, unsigned int height, int mask, COLORREF fg, COLORREF bg) @@ -1639,8 +1698,8 @@ xbm_create_bitmap_from_data (HDC hdc, char *data, void *bmp_buf = 0; unsigned char *new_data, *new_offset; int i, j; - BITMAPINFO* bmp_info = - xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD)); + BITMAPINFO *bmp_info = + (BITMAPINFO*) xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD)); HBITMAP bitmap; if (!bmp_info) @@ -1661,9 +1720,9 @@ xbm_create_bitmap_from_data (HDC hdc, char *data, for (j=0; j> 4]); + ((flip_table[bite & 0xf] << 4) + flip_table[bite >> 4]); } } @@ -1720,10 +1779,10 @@ xbm_create_bitmap_from_data (HDC hdc, char *data, image instance accordingly. */ static void -init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii, +init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii, int width, int height, /* Note that data is in ext-format! */ - CONST char *bits, + const char *bits, Lisp_Object instantiator, Lisp_Object pointer_fg, Lisp_Object pointer_bg, @@ -1732,17 +1791,16 @@ init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii, Lisp_Object mask_filename) { Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - struct frame* f = XFRAME (DEVICE_SELECTED_FRAME (XDEVICE (device))); Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground); Lisp_Object background = find_keyword_in_vector (instantiator, Q_background); enum image_instance_type type; COLORREF black = PALETTERGB (0,0,0); COLORREF white = PALETTERGB (255,255,255); + HDC hdc; - HDC hdc = FRAME_MSWINDOWS_CDC (f); + CHECK_MSGDI_DEVICE (device); - if (!DEVICE_MSWINDOWS_P (XDEVICE (device))) - signal_simple_error ("Not an MS-Windows device", device); + hdc = get_device_compdc (XDEVICE (device)); if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) && (dest_mask & IMAGE_COLOR_PIXMAP_MASK)) @@ -1767,11 +1825,13 @@ init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii, IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = find_keyword_in_vector (instantiator, Q_file); - IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width; - IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height; + IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = width; + IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = height; IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1; XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0); XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0); + init_image_instance_geometry (ii); + IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask : xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height, TRUE, black, white); @@ -1843,7 +1903,7 @@ init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii, break; default: - abort (); + ABORT (); } } @@ -1852,29 +1912,28 @@ xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator, Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, int width, int height, /* Note that data is in ext-format! */ - CONST char *bits) + const char *bits) { Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data); Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file); - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - struct frame* f = XFRAME (DEVICE_SELECTED_FRAME - (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)))); - HDC hdc = FRAME_MSWINDOWS_CDC (f); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + HDC hdc = get_device_compdc (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))); HBITMAP mask = 0; - CONST char *gcc_may_you_rot_in_hell; if (!NILP (mask_data)) { - GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))), - gcc_may_you_rot_in_hell); - mask = - xbm_create_bitmap_from_data ( hdc, - (unsigned char *) - gcc_may_you_rot_in_hell, - XINT (XCAR (mask_data)), - XINT (XCAR (XCDR (mask_data))), FALSE, - PALETTERGB (0,0,0), - PALETTERGB (255,255,255)); + const char *ext_data; + + TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (mask_data))), + C_STRING_ALLOCA, ext_data, + Qbinary); + mask = xbm_create_bitmap_from_data (hdc, + (unsigned char *) ext_data, + XINT (XCAR (mask_data)), + XINT (XCAR (XCDR (mask_data))), + FALSE, + PALETTERGB (0,0,0), + PALETTERGB (255,255,255)); } init_image_instance_from_xbm_inline (ii, width, height, bits, @@ -1891,16 +1950,17 @@ mswindows_xbm_instantiate (Lisp_Object image_instance, int dest_mask, Lisp_Object domain) { Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); - CONST char *gcc_go_home; + const char *ext_data; assert (!NILP (data)); - GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))), - gcc_go_home); + TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (data))), + C_STRING_ALLOCA, ext_data, + Qbinary); xbm_instantiate_1 (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, XINT (XCAR (data)), - XINT (XCAR (XCDR (data))), gcc_go_home); + XINT (XCAR (XCDR (data))), ext_data); } #ifdef HAVE_XFACE @@ -1917,6 +1977,9 @@ mswindows_xbm_instantiate (Lisp_Object image_instance, #ifdef __cplusplus extern "C" { #endif +#ifndef __STDC__ /* Needed to avoid prototype warnings */ +#define __STDC__ +#endif #include #ifdef __cplusplus } @@ -1935,12 +1998,14 @@ mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiato Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); int i, stattis; char *p, *bits, *bp; - CONST char * volatile emsg = 0; - CONST char * volatile dstring; + const char * volatile emsg = 0; + const char * volatile dstring; assert (!NILP (data)); - GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring); + TO_EXTERNAL_FORMAT (LISP_STRING, data, + C_STRING_ALLOCA, dstring, + Qbinary); if ((p = strchr (dstring, ':'))) { @@ -1996,7 +2061,7 @@ mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiato /************************************************************************/ static void -mswindows_print_image_instance (struct Lisp_Image_Instance *p, +mswindows_print_image_instance (Lisp_Image_Instance *p, Lisp_Object printcharfun, int escapeflag) { @@ -2029,13 +2094,21 @@ extern int debug_widget_instances; #endif static void -mswindows_finalize_image_instance (struct Lisp_Image_Instance *p) +finalize_destroy_window (void *win) +{ + DestroyWindow ((HWND) win); +} + +static void +mswindows_finalize_image_instance (Lisp_Image_Instance *p) { - if (DEVICE_LIVE_P (XDEVICE (p->device))) + if (!p->data) + return; + + if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p)))) { - if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET - || - IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) + if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (p)) + & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)) { #ifdef DEBUG_WIDGETS debug_widget_instances--; @@ -2043,8 +2116,14 @@ mswindows_finalize_image_instance (struct Lisp_Image_Instance *p) #endif if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) { - DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p)); - DestroyWindow (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)); + /* DestroyWindow is not safe here, as it will send messages + to our window proc. */ + register_post_gc_action + (finalize_destroy_window, + (void *) (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p))); + register_post_gc_action + (finalize_destroy_window, + (void *) (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p))); IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0; } } @@ -2085,27 +2164,80 @@ mswindows_finalize_image_instance (struct Lisp_Image_Instance *p) /* subwindow and widget support */ /************************************************************************/ +static HFONT +mswindows_widget_hfont (Lisp_Image_Instance *p, + Lisp_Object domain) +{ + Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (p); + int under = FACE_UNDERLINE_P (face, domain); + int strike = FACE_STRIKETHRU_P (face, domain); + Lisp_Object font = query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (p), + face, domain); + + return mswindows_get_hfont (XFONT_INSTANCE (font), under, strike); +} + +static HDWP +begin_defer_window_pos (struct frame *f) +{ +#ifdef DEFER_WINDOW_POS + if (FRAME_MSWINDOWS_DATA (f)->hdwp == 0) + FRAME_MSWINDOWS_DATA (f)->hdwp = BeginDeferWindowPos (10); +#endif + return FRAME_MSWINDOWS_DATA (f)->hdwp; +} + /* unmap the image if it is a widget. This is used by redisplay via redisplay_unmap_subwindows */ static void -mswindows_unmap_subwindow (struct Lisp_Image_Instance *p) +mswindows_unmap_subwindow (Lisp_Image_Instance *p) { if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) { +#ifdef DEFER_WINDOW_POS + struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p)); + HDWP hdwp = begin_defer_window_pos (f); + HDWP new_hdwp; + new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), + NULL, + 0, 0, 0, 0, + SWP_HIDEWINDOW | SWP_NOACTIVATE | + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER + /* Setting this flag causes the call to + DeferWindowPos to fail with + "Invalid parameter". I don't understand + why we bother to try and set this + anyway. -- ben */ + /* | SWP_NOSENDCHANGING */ + ); + if (!new_hdwp) + mswindows_output_last_error ("unmapping"); + else + hdwp = new_hdwp; + FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp; +#else SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), NULL, 0, 0, 0, 0, - SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE - | SWP_NOSENDCHANGING); + SWP_HIDEWINDOW | SWP_NOACTIVATE | + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER ); +#endif + if (GetFocus() == WIDGET_INSTANCE_MSWINDOWS_HANDLE (p)) + SetFocus (GetParent (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p))); } } /* map the subwindow. This is used by redisplay via redisplay_output_subwindow */ static void -mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y, +mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y, struct display_glyph_area* dga) { +#ifdef DEFER_WINDOW_POS + struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p)); + HDWP hdwp = begin_defer_window_pos (f); + HDWP new_hdwp; +#endif /* move the window before mapping it ... */ SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), NULL, @@ -2119,77 +2251,159 @@ mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y, SWP_NOZORDER | SWP_NOSIZE | SWP_NOCOPYBITS | SWP_NOSENDCHANGING); /* ... now map it - we are not allowed to move it at the same time. */ - SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), - NULL, - 0, 0, 0, 0, - SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE - | SWP_SHOWWINDOW | SWP_NOCOPYBITS - | SWP_NOSENDCHANGING); + if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p)) + { +#ifdef DEFER_WINDOW_POS + new_hdwp = DeferWindowPos + (hdwp, + IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), + NULL, 0, 0, 0, 0, + SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE + | SWP_SHOWWINDOW + /* | SWP_NOCOPYBITS */ + /* Setting this flag causes the call to + DeferWindowPos to fail with + "Invalid parameter". I don't understand + why we bother to try and set this + anyway. -- ben */ + /* | SWP_NOSENDCHANGING */ + | SWP_NOACTIVATE); + if (!new_hdwp) + mswindows_output_last_error ("mapping"); + else + hdwp = new_hdwp; + FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp; +#else + SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), + NULL, + 0, 0, 0, 0, + SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE + | SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_NOACTIVATE); + + /* Doing this once does not seem to be enough, for instance when + mapping the search dialog this gets called four times. If we + only set on the first time through then the subwindow never + gets focus as intended. However, doing this everytime doesn't + seem so bad, after all we only need to redo this after the + focus changes - and if that happens resetting the initial + focus doesn't seem so bad. */ + if (IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (p)) + SetFocus (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p)); +#endif + } } /* resize the subwindow instance */ static void -mswindows_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h) +mswindows_resize_subwindow (Lisp_Image_Instance* ii, int w, int h) { /* Set the size of the control .... */ - SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), - NULL, - 0, 0, w, h, - SWP_NOZORDER | SWP_NOMOVE - | SWP_NOCOPYBITS | SWP_NOSENDCHANGING); + if (!SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), + NULL, + 0, 0, w, h, + SWP_NOZORDER | SWP_NOMOVE + | SWP_NOCOPYBITS | SWP_NOSENDCHANGING)) + mswindows_output_last_error ("resizing"); +} + +/* Simply resize the window here. */ +static void +mswindows_redisplay_subwindow (Lisp_Image_Instance *p) +{ + mswindows_resize_subwindow (p, + IMAGE_INSTANCE_WIDTH (p), + IMAGE_INSTANCE_HEIGHT (p)); } /* when you click on a widget you may activate another widget this needs to be checked and all appropriate widgets updated */ static void -mswindows_update_subwindow (struct Lisp_Image_Instance *p) +mswindows_redisplay_widget (Lisp_Image_Instance *p) { - if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) + /* Possibly update the face font and colors. */ + if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (p)) + && (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) + || XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed + || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))) { - /* buttons checked or otherwise */ - if ( EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qbutton)) - { - if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (p))) - SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), - BM_SETCHECK, (WPARAM)BST_CHECKED, 0); - else - SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), - BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); - } - /* set the widget font from the widget face */ SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), WM_SETFONT, - (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT - (XFONT_INSTANCE (widget_face_font_info - (IMAGE_INSTANCE_SUBWINDOW_FRAME (p), - IMAGE_INSTANCE_WIDGET_FACE (p), - 0, 0))), + (WPARAM) mswindows_widget_hfont + (p, IMAGE_INSTANCE_FRAME (p)), MAKELPARAM (TRUE, 0)); } + /* Possibly update the dimensions. */ + if (IMAGE_INSTANCE_SIZE_CHANGED (p)) + { + mswindows_resize_subwindow (p, + IMAGE_INSTANCE_WIDTH (p), + IMAGE_INSTANCE_HEIGHT (p)); + } + /* Possibly update the text in the widget. */ + if (IMAGE_INSTANCE_TEXT_CHANGED (p) + && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (p))) + { + Extbyte* lparam=0; + TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (p), + C_STRING_ALLOCA, lparam, + Qnative); + SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), + WM_SETTEXT, 0, (LPARAM)lparam); + } + /* Set active state. */ + if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) + { + Lisp_Object item = IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p); + LONG style = GetWindowLong + (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), + GWL_STYLE); + + if (CONSP (item)) + item = XCAR (item); + + if (gui_item_active_p (item)) + SetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), + GWL_STYLE, style & ~WS_DISABLED); + else + SetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), + GWL_STYLE, style | WS_DISABLED); + } +} + +/* Account for some of the limitations with widget images. */ +static int +mswindows_widget_border_width (void) +{ + return DEFAULT_WIDGET_BORDER_WIDTH; } -/* register widgets into our hastable so that we can cope with the +/* register widgets into our hashtable so that we can cope with the callbacks. The hashtable is weak so deregistration is handled automatically */ static int -mswindows_register_gui_item (Lisp_Object gui, Lisp_Object domain) +mswindows_register_gui_item (Lisp_Object image_instance, + Lisp_Object gui, Lisp_Object domain) { - Lisp_Object frame = FW_FRAME (domain); + Lisp_Object frame = DOMAIN_FRAME (domain); struct frame* f = XFRAME (frame); - int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f), + int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f), gui, WIDGET_GLYPH_SLOT); - Fputhash (make_int (id), - XGUI_ITEM (gui)->callback, - FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f)); + Fputhash (make_int (id), image_instance, + FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f)); + Fputhash (make_int (id), XGUI_ITEM (gui)->callback, + FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f)); + Fputhash (make_int (id), XGUI_ITEM (gui)->callback_ex, + FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f)); return id; } static int mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain) { - return mswindows_register_gui_item (XIMAGE_INSTANCE_WIDGET_ITEM (instance), + return mswindows_register_gui_item (instance, + XIMAGE_INSTANCE_WIDGET_ITEM (instance), domain); } @@ -2198,14 +2412,12 @@ mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instant Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - struct device* d = XDEVICE (device); - Lisp_Object frame = FW_FRAME (domain); + Lisp_Object frame = DOMAIN_FRAME (domain); HWND wnd; - if (!DEVICE_MSWINDOWS_P (d)) - signal_simple_error ("Not an mswindows device", device); + CHECK_MSWINDOWS_DEVICE (device); /* have to set the type this late in case there is no device instantiation for a widget */ @@ -2250,8 +2462,8 @@ mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instant } static int -mswindows_image_instance_equal (struct Lisp_Image_Instance *p1, - struct Lisp_Image_Instance *p2, int depth) +mswindows_image_instance_equal (Lisp_Image_Instance *p1, + Lisp_Image_Instance *p2, int depth) { switch (IMAGE_INSTANCE_TYPE (p1)) { @@ -2271,7 +2483,7 @@ mswindows_image_instance_equal (struct Lisp_Image_Instance *p1, } static unsigned long -mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth) +mswindows_image_instance_hash (Lisp_Image_Instance *p, int depth) { switch (IMAGE_INSTANCE_TYPE (p)) { @@ -2292,7 +2504,7 @@ mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth) methods are called. */ static void -mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, +mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii, int slices, enum image_instance_type type) { @@ -2319,43 +2531,41 @@ static void mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain, - CONST char* class, int flags, int exflags) + const char* class, int flags, int exflags) { /* this function can call lisp */ - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style; - struct device* d = XDEVICE (device); - Lisp_Object frame = FW_FRAME (domain); + Lisp_Object frame = DOMAIN_FRAME (domain); Extbyte* nm=0; HWND wnd; int id = 0xffff; Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); - struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui); + Lisp_Gui_Item* pgui = XGUI_ITEM (gui); - if (!DEVICE_MSWINDOWS_P (d)) - signal_simple_error ("Not an mswindows device", device); + CHECK_MSWINDOWS_DEVICE (device); if (!gui_item_active_p (gui)) flags |= WS_DISABLED; style = pgui->style; - if (!NILP (pgui->callback)) + if (!NILP (pgui->callback) || !NILP (pgui->callback_ex)) { id = mswindows_register_widget_instance (image_instance, domain); } - /* have to set the type this late in case there is no device - instantiation for a widget */ - IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET; + if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) - GET_C_STRING_OS_DATA_ALLOCA (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm); + TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (ii), + C_STRING_ALLOCA, nm, + Qnative); /* allocate space for the clip window and then allocate the clip window */ ii->data = xnew_and_zero (struct mswindows_subwindow_data); if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii) = CreateWindowEx( - 0, /* EX flags */ + WS_EX_CONTROLPARENT, /* EX flags */ XEMACS_CONTROL_CLASS, 0, /* text */ WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD, @@ -2364,7 +2574,7 @@ mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiat IMAGE_INSTANCE_WIDGET_WIDTH (ii), IMAGE_INSTANCE_WIDGET_HEIGHT (ii), /* parent window */ - FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), + DOMAIN_MSWINDOWS_HANDLE (domain), (HMENU)id, /* No menu */ NULL, /* must be null for this class */ NULL)) == NULL) @@ -2394,19 +2604,38 @@ mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiat IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd; SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance)); /* set the widget font from the widget face */ - SendMessage (wnd, WM_SETFONT, - (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT - (XFONT_INSTANCE (widget_face_font_info - (domain, - IMAGE_INSTANCE_WIDGET_FACE (ii), - 0, 0))), - MAKELPARAM (TRUE, 0)); + if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) + SendMessage (wnd, WM_SETFONT, + (WPARAM) mswindows_widget_hfont (ii, domain), + MAKELPARAM (TRUE, 0)); +} + +/* Instantiate a native layout widget. */ +static void +mswindows_native_layout_instantiate (Lisp_Object image_instance, + Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + + mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, "STATIC", + /* Approximation to styles available with + an XEmacs layout. */ + (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii), + Qetched_in) || + EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii), + Qetched_out) || + GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)) + ? SS_ETCHEDFRAME : SS_SUNKEN) | DS_CONTROL, + 0); } /* Instantiate a button widget. Unfortunately instantiated widgets are particular to a frame since they need to have a parent. It's not like images where you just select the image into the context you - want to display it in and BitBlt it. So images instances can have a + want to display it in and BitBlt it. So image instances can have a many-to-one relationship with things you see, whereas widgets can only be one-to-one (i.e. per frame) */ static void @@ -2414,18 +2643,18 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { - /* this function can call lisp */ - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + /* This function can call lisp */ + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); HWND wnd; - int flags = BS_NOTIFY; + int flags = WS_TABSTOP | BS_NOTIFY; + /* BS_NOTIFY #### is needed to get exotic feedback only. Since we + seem to want nothing beyond BN_CLICK, the style is perhaps not + necessary -- kkm */ Lisp_Object style; Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); - struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui); + Lisp_Gui_Item* pgui = XGUI_ITEM (gui); Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); - if (!gui_item_active_p (gui)) - flags |= WS_DISABLED; - if (!NILP (glyph)) { if (!IMAGE_INSTANCEP (glyph)) @@ -2438,6 +2667,8 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat style = pgui->style; + /* #### consider using the default face for radio and toggle + buttons. */ if (EQ (style, Qradio)) { flags |= BS_RADIOBUTTON; @@ -2447,11 +2678,13 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat flags |= BS_AUTOCHECKBOX; } else - flags |= BS_DEFPUSHBUTTON; + { + flags |= BS_DEFPUSHBUTTON; + } mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, - pointer_bg, dest_mask, domain, "BUTTON", flags, - WS_EX_CONTROLPARENT); + pointer_bg, dest_mask, domain, "BUTTON", + flags, 0); wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); /* set the checked state */ @@ -2460,17 +2693,35 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat else SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); /* add the image if one was given */ - if (!NILP (glyph) && IMAGE_INSTANCEP (glyph)) + if (!NILP (glyph) && IMAGE_INSTANCEP (glyph) + && + IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph))) { SendMessage (wnd, BM_SETIMAGE, (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ? IMAGE_BITMAP : IMAGE_ICON), - (LPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ? - XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) : - XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph))); + (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ? + (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) : + (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph))); } } +/* Update the state of a button. */ +static void +mswindows_button_redisplay (Lisp_Object image_instance) +{ + /* This function can GC if IN_REDISPLAY is false. */ + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + + /* buttons checked or otherwise */ + if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii))) + SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), + BM_SETCHECK, (WPARAM)BST_CHECKED, 0); + else + SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), + BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); +} + /* instantiate an edit control */ static void mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, @@ -2480,8 +2731,7 @@ mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instan mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP - | WS_BORDER, - WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT); + | WS_BORDER, WS_EX_CLIENTEDGE); } /* instantiate a progress gauge */ @@ -2491,11 +2741,11 @@ mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object in int dest_mask, Lisp_Object domain) { HWND wnd; - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Object val; mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, PROGRESS_CLASS, - WS_TABSTOP | WS_BORDER | PBS_SMOOTH, - WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT); + WS_BORDER | PBS_SMOOTH, WS_EX_CLIENTEDGE); wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); /* set the colors */ #ifdef PBS_SETBKCOLOR @@ -2504,7 +2754,7 @@ mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object in (XCOLOR_INSTANCE (FACE_BACKGROUND (XIMAGE_INSTANCE_WIDGET_FACE (ii), - XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))))); + XIMAGE_INSTANCE_FRAME (ii)))))); #endif #ifdef PBS_SETBARCOLOR SendMessage (wnd, PBS_SETBARCOLOR, 0, @@ -2512,8 +2762,12 @@ mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object in (XCOLOR_INSTANCE (FACE_FOREGROUND (XIMAGE_INSTANCE_WIDGET_FACE (ii), - XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))))); + XIMAGE_INSTANCE_FRAME (ii)))))); #endif + val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEMS (ii))->value; + CHECK_INT (val); + SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), + PBM_SETPOS, (WPARAM)XINT (val), 0); } /* instantiate a tree view widget */ @@ -2531,13 +2785,17 @@ static HTREEITEM add_tree_item (Lisp_Object image_instance, if (GUI_ITEMP (item)) { - tvitem.item.lParam = mswindows_register_gui_item (item, domain); + tvitem.item.lParam = mswindows_register_gui_item (image_instance, + item, domain); tvitem.item.mask |= TVIF_PARAM; - GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name, - tvitem.item.pszText); + TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name, + C_STRING_ALLOCA, tvitem.item.pszText, + Qnative); } else - GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.item.pszText); + TO_EXTERNAL_FORMAT (LISP_STRING, item, + C_STRING_ALLOCA, tvitem.item.pszText, + Qnative); tvitem.item.cchTextMax = strlen (tvitem.item.pszText); @@ -2574,12 +2832,12 @@ mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instant Lisp_Object rest; HWND wnd; HTREEITEM parent; - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, WC_TREEVIEW, WS_TABSTOP | WS_BORDER | PBS_SMOOTH | TVS_HASLINES | TVS_HASBUTTONS, - WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT); + WS_EX_CLIENTEDGE); wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); @@ -2599,32 +2857,71 @@ mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instant } } +/* Set the properties of a tree view. */ +static void +mswindows_tree_view_redisplay (Lisp_Object image_instance) +{ + /* This function can GC if IN_REDISPLAY is false. */ + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + + if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) + { + HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); + Lisp_Object rest; + HTREEITEM parent; + /* Delete previous items. */ + SendMessage (wnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); + /* define a root */ + parent = add_tree_item (image_instance, wnd, NULL, + XCAR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)), + TRUE, IMAGE_INSTANCE_DOMAIN (ii)); + + /* recursively add items to the tree view */ + /* add items to the tab */ + LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))) + { + if (LISTP (XCAR (rest))) + add_tree_item_list (image_instance, wnd, parent, XCAR (rest), + IMAGE_INSTANCE_DOMAIN (ii)); + else + add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, + IMAGE_INSTANCE_DOMAIN (ii)); + } + } +} + /* instantiate a tab control */ -static TC_ITEM* add_tab_item (Lisp_Object image_instance, - HWND wnd, Lisp_Object item, - Lisp_Object domain, int index) +static int +add_tab_item (Lisp_Object image_instance, + HWND wnd, Lisp_Object item, + Lisp_Object domain, int i) { - TC_ITEM tvitem, *ret; + TC_ITEM tvitem; + int ret = 0; tvitem.mask = TCIF_TEXT; if (GUI_ITEMP (item)) { - tvitem.lParam = mswindows_register_gui_item (item, domain); + tvitem.lParam = mswindows_register_gui_item (image_instance, + item, domain); tvitem.mask |= TCIF_PARAM; - GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name, - tvitem.pszText); + TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name, + C_STRING_ALLOCA, tvitem.pszText, + Qnative); } else { CHECK_STRING (item); - GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.pszText); + TO_EXTERNAL_FORMAT (LISP_STRING, item, + C_STRING_ALLOCA, tvitem.pszText, + Qnative); } tvitem.cchTextMax = strlen (tvitem.pszText); - if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM, - index, (LPARAM)&tvitem)) < 0) + if ((ret = SendMessage (wnd, TCM_INSERTITEM, + i, (LPARAM)&tvitem)) < 0) signal_simple_error ("error adding tab entry", item); return ret; @@ -2635,57 +2932,113 @@ mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object insta Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { + /* This function can call lisp */ Lisp_Object rest; HWND wnd; - int index = 0; - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + int i = 0, selected = 0; + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation); + unsigned int flags = WS_TABSTOP; + + if (EQ (orient, Qleft) || EQ (orient, Qright)) + { + flags |= TCS_VERTICAL | TCS_MULTILINE; + } + if (EQ (orient, Qright) || EQ (orient, Qbottom)) + { + flags |= TCS_BOTTOM; + } + mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, WC_TABCONTROL, /* borders don't suit tabs so well */ - WS_TABSTOP, - WS_EX_CONTROLPARENT); - + flags, 0); wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); /* add items to the tab */ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) { - add_tab_item (image_instance, wnd, XCAR (rest), domain, index); - index++; + int idx = add_tab_item (image_instance, wnd, XCAR (rest), domain, i); + assert (idx == i); + if (gui_item_selected_p (XCAR (rest))) + selected = i; + i++; } + SendMessage (wnd, TCM_SETCURSEL, selected, 0); } -/* set the properties of a tab control */ -static Lisp_Object -mswindows_tab_control_set_property (Lisp_Object image_instance, Lisp_Object prop, - Lisp_Object val) +/* Set the properties of a tab control. */ +static void +mswindows_tab_control_redisplay (Lisp_Object image_instance) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - - if (EQ (prop, Q_items)) + /* This function can GC if IN_REDISPLAY is false. */ + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); +#ifdef DEBUG_WIDGET_OUTPUT + stderr_out ("tab control %p redisplayed\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); +#endif + if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) + || + IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii)) { HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); - int index = 0; + int i = 0, selected_idx = 0; Lisp_Object rest; - check_valid_item_list_1 (val); - /* delete the pre-existing items */ - SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0); + assert (!NILP (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); - IMAGE_INSTANCE_WIDGET_ITEMS (ii) = - Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)), - parse_gui_item_tree_children (val)); - - /* add items to the tab */ - LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) + /* If only the order has changed then simply select the first + one. This stops horrendous rebuilding of the tabs each time + you click on one. */ + if (tab_control_order_only_changed (image_instance)) { - add_tab_item (image_instance, wnd, XCAR (rest), - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii), index); - index++; + Lisp_Object selected = + gui_item_list_find_selected + (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ? + XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) : + XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))); + + LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) + { + if (gui_item_equal_sans_selected (XCAR (rest), selected, 0)) + { + Lisp_Object old_selected = gui_item_list_find_selected + (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); + + /* Pick up the new selected item. */ + XGUI_ITEM (old_selected)->selected = + XGUI_ITEM (XCAR (rest))->selected; + XGUI_ITEM (XCAR (rest))->selected = + XGUI_ITEM (selected)->selected; + /* We're not actually changing the items. */ + IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; + IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil; + + SendMessage (wnd, TCM_SETCURSEL, i, 0); +#ifdef DEBUG_WIDGET_OUTPUT + stderr_out ("tab control %p selected item %d\n", + IMAGE_INSTANCE_SUBWINDOW_ID (ii), i); +#endif + break; + } + i++; + } } + else + { + /* delete the pre-existing items */ + SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0); - return Qt; + /* add items to the tab */ + LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))) + { + add_tab_item (image_instance, wnd, XCAR (rest), + IMAGE_INSTANCE_FRAME (ii), i); + if (gui_item_selected_p (XCAR (rest))) + selected_idx = i; + i++; + } + SendMessage (wnd, TCM_SETCURSEL, selected_idx, 0); + } } - return Qunbound; } /* instantiate a static control possible for putting other things in */ @@ -2707,8 +3060,7 @@ mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instant { mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "SCROLLBAR", - 0, - WS_EX_CLIENTEDGE ); + WS_TABSTOP, WS_EX_CLIENTEDGE); } /* instantiate a combo control */ @@ -2717,13 +3069,11 @@ mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instant Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - HANDLE wnd; + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + HWND wnd; Lisp_Object rest; - Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties), - Q_items, Qnil); - int len; - GET_LIST_LENGTH (data, len); + Lisp_Object items = find_keyword_in_vector (instantiator, Q_items); + int len, height; /* Maybe ought to generalise this more but it may be very windows specific. In windows the window height of a combo box is the @@ -2731,26 +3081,40 @@ mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instant before creating the window and then reset it to a single line after the window is created so that redisplay does the right thing. */ - widget_instantiate_1 (image_instance, instantiator, pointer_fg, - pointer_bg, dest_mask, domain, len + 1, 0, 0); + widget_instantiate (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain); + + /* We now have everything right apart from the height. */ + default_face_font_info (domain, 0, 0, &height, 0, 0); + GET_LIST_LENGTH (items, len); + height = (height + DEFAULT_WIDGET_BORDER_WIDTH * 2 ) * len; + IMAGE_INSTANCE_HEIGHT (ii) = height; + + /* Now create the widget. */ mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "COMBOBOX", WS_BORDER | WS_TABSTOP | CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_HASSTRINGS | WS_VSCROLL, - WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT); - /* reset the height */ - widget_text_to_pixel_conversion (domain, - IMAGE_INSTANCE_WIDGET_FACE (ii), 1, 0, - &IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii), 0); + WS_EX_CLIENTEDGE); + /* Reset the height. layout will probably do this safely, but better make sure. */ + image_instance_layout (image_instance, + IMAGE_UNSPECIFIED_GEOMETRY, + IMAGE_UNSPECIFIED_GEOMETRY, + IMAGE_UNCHANGED_GEOMETRY, + IMAGE_UNCHANGED_GEOMETRY, + domain); + wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); /* add items to the combo box */ SendMessage (wnd, CB_RESETCONTENT, 0, 0); - LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil)) + LIST_LOOP (rest, items) { Extbyte* lparam; - GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), lparam); + TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (rest), + C_STRING_ALLOCA, lparam, + Qnative); if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR) signal_simple_error ("error adding combo entries", instantiator); } @@ -2760,16 +3124,16 @@ mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instant static Lisp_Object mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); /* get the text from a control */ if (EQ (prop, Q_text)) { Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0); - Extbyte* buf =alloca (len+1); + Extbyte *buf = (Extbyte*) alloca (len+1); SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf); - return build_ext_string (buf, FORMAT_OS); + return build_ext_string (buf, Qnative); } return Qunbound; } @@ -2778,8 +3142,8 @@ mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop) static Lisp_Object mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); /* check the state of a button */ if (EQ (prop, Q_selected)) { @@ -2795,61 +3159,49 @@ mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop) static Lisp_Object mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); /* get the text from a control */ if (EQ (prop, Q_text)) { long item = SendMessage (wnd, CB_GETCURSEL, 0, 0); Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0); - Extbyte* buf = alloca (len+1); + Extbyte* buf = (Extbyte*) alloca (len+1); SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf); - return build_ext_string (buf, FORMAT_OS); - } - return Qunbound; -} - -/* set the properties of a control */ -static Lisp_Object -mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop, - Lisp_Object val) -{ - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - - if (EQ (prop, Q_text)) - { - Extbyte* lparam=0; - CHECK_STRING (val); - GET_C_STRING_OS_DATA_ALLOCA (val, lparam); - SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), - WM_SETTEXT, 0, (LPARAM)lparam); - return Qt; + return build_ext_string (buf, Qnative); } return Qunbound; } -/* set the properties of a progres guage */ -static Lisp_Object -mswindows_progress_gauge_set_property (Lisp_Object image_instance, Lisp_Object prop, - Lisp_Object val) +/* set the properties of a progress gauge */ +static void +mswindows_progress_gauge_redisplay (Lisp_Object image_instance) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - if (EQ (prop, Q_percent)) + if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) { + Lisp_Object val; +#ifdef ERROR_CHECK_GLYPHS + assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))); +#endif + val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value; +#ifdef DEBUG_WIDGET_OUTPUT + stderr_out ("progress gauge displayed value on %p updated to %ld\n", + WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), + XINT(val)); +#endif CHECK_INT (val); SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), PBM_SETPOS, (WPARAM)XINT (val), 0); - return Qt; } - return Qunbound; } LRESULT WINAPI -mswindows_control_wnd_proc (HWND hwnd, UINT message, +mswindows_control_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - switch (message) + switch (msg) { case WM_NOTIFY: case WM_COMMAND: @@ -2859,9 +3211,9 @@ mswindows_control_wnd_proc (HWND hwnd, UINT message, case WM_CTLCOLORSTATIC: case WM_CTLCOLORSCROLLBAR: - return mswindows_wnd_proc (GetParent (hwnd), message, wParam, lParam); + return mswindows_wnd_proc (GetParent (hwnd), msg, wParam, lParam); default: - return DefWindowProc (hwnd, message, wParam, lParam); + return DefWindowProc (hwnd, msg, wParam, lParam); } } @@ -2882,94 +3234,105 @@ syms_of_glyphs_mswindows (void) void console_type_create_glyphs_mswindows (void) { - /* image methods */ - + /* image methods - display */ CONSOLE_HAS_METHOD (mswindows, print_image_instance); CONSOLE_HAS_METHOD (mswindows, finalize_image_instance); CONSOLE_HAS_METHOD (mswindows, unmap_subwindow); CONSOLE_HAS_METHOD (mswindows, map_subwindow); - CONSOLE_HAS_METHOD (mswindows, update_subwindow); + CONSOLE_HAS_METHOD (mswindows, redisplay_subwindow); + CONSOLE_HAS_METHOD (mswindows, resize_subwindow); + CONSOLE_HAS_METHOD (mswindows, redisplay_widget); CONSOLE_HAS_METHOD (mswindows, image_instance_equal); CONSOLE_HAS_METHOD (mswindows, image_instance_hash); CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage); CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file); - CONSOLE_HAS_METHOD (mswindows, resize_subwindow); + CONSOLE_HAS_METHOD (mswindows, widget_border_width); + + /* image methods - printer */ + CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_image_instance); + CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_image_instance); + CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_equal); + CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_hash); + CONSOLE_INHERITS_METHOD (msprinter, mswindows, init_image_instance_from_eimage); + CONSOLE_INHERITS_METHOD (msprinter, mswindows, locate_pixmap_file); } void image_instantiator_format_create_glyphs_mswindows (void) { - IIFORMAT_VALID_CONSOLE (mswindows, nothing); - IIFORMAT_VALID_CONSOLE (mswindows, string); - IIFORMAT_VALID_CONSOLE (mswindows, layout); - IIFORMAT_VALID_CONSOLE (mswindows, formatted_string); - IIFORMAT_VALID_CONSOLE (mswindows, inherit); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, nothing); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, string); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, formatted_string); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, inherit); /* image-instantiator types */ + INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm); + INITIALIZE_DEVICE_IIFORMAT (msprinter, xbm); + IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate); + IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xbm, instantiate); #ifdef HAVE_XPM INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm); + INITIALIZE_DEVICE_IIFORMAT (msprinter, xpm); IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate); + IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xpm, instantiate); #endif - INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm); - IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate); #ifdef HAVE_XFACE INITIALIZE_DEVICE_IIFORMAT (mswindows, xface); + INITIALIZE_DEVICE_IIFORMAT (msprinter, xface); IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate); + IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xface, instantiate); #endif #ifdef HAVE_JPEG - IIFORMAT_VALID_CONSOLE (mswindows, jpeg); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, jpeg); #endif #ifdef HAVE_TIFF - IIFORMAT_VALID_CONSOLE (mswindows, tiff); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, tiff); #endif #ifdef HAVE_PNG - IIFORMAT_VALID_CONSOLE (mswindows, png); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, png); #endif #ifdef HAVE_GIF - IIFORMAT_VALID_CONSOLE (mswindows, gif); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, gif); #endif #ifdef HAVE_WIDGETS + INITIALIZE_DEVICE_IIFORMAT (mswindows, widget); + IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property); + /* layout widget */ + IIFORMAT_VALID_CONSOLE (mswindows, layout); + INITIALIZE_DEVICE_IIFORMAT (mswindows, native_layout); + IIFORMAT_HAS_DEVMETHOD (mswindows, native_layout, instantiate); /* button widget */ INITIALIZE_DEVICE_IIFORMAT (mswindows, button); IIFORMAT_HAS_DEVMETHOD (mswindows, button, property); IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate); - + IIFORMAT_HAS_DEVMETHOD (mswindows, button, redisplay); + /* edit-field widget */ INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field); IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate); - + /* subwindow */ INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow); IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate); - - INITIALIZE_DEVICE_IIFORMAT (mswindows, widget); - IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property); - IIFORMAT_HAS_DEVMETHOD (mswindows, widget, set_property); - /* label */ INITIALIZE_DEVICE_IIFORMAT (mswindows, label); IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate); - /* combo box */ INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box); IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property); IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate); - /* scrollbar */ INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar); IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate); - /* progress gauge */ INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge); - IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, set_property); + IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, redisplay); IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate); - /* tree view widget */ INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view); - /* IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);*/ IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate); - + IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, redisplay); /* tab control widget */ INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control); IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate); - IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, set_property); + IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, redisplay); #endif /* windows bitmap format */ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp"); @@ -2980,7 +3343,7 @@ image_instantiator_format_create_glyphs_mswindows (void) IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string); IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string); - IIFORMAT_VALID_CONSOLE (mswindows, bmp); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, bmp); /* mswindows resources */ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource, @@ -2995,7 +3358,7 @@ image_instantiator_format_create_glyphs_mswindows (void) check_valid_resource_symbol); IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id); IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string); - IIFORMAT_VALID_CONSOLE (mswindows, mswindows_resource); + IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, mswindows_resource); } void