X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fglyphs-msw.c;h=d3c11b6984849b6f1f8ca6ad92725f1fd811d168;hb=ea1ea793fe6e244ef5555ed983423a204101af13;hp=6ee899ed2dcb63a03552cf2279ad5a3341b3d264;hpb=6883ee56ec887c2c48abe5b06b5e66aa74031910;p=chise%2Fxemacs-chise.git- diff --git a/src/glyphs-msw.c b/src/glyphs-msw.c index 6ee899e..d3c11b6 100644 --- a/src/glyphs-msw.c +++ b/src/glyphs-msw.c @@ -1,5 +1,5 @@ -/* mswindows-specific Lisp objects. - Copyright (C) 1998 Andy Piper. +/* mswindows-specific glyph objects. + Copyright (C) 1998, 1999 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 buts from +/* written by Andy Piper plagerising bits from glyphs-x.c */ #include @@ -32,6 +32,8 @@ Boston, MA 02111-1307, USA. */ #include "glyphs-msw.h" #include "objects-msw.h" +#include "window.h" +#include "elhash.h" #include "buffer.h" #include "frame.h" #include "insdel.h" @@ -45,7 +47,46 @@ Boston, MA 02111-1307, USA. */ #endif #include #include +#ifdef HAVE_XFACE +#include +#endif + +#define WIDGET_GLYPH_SLOT 0 +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 +#ifdef HAVE_TIFF +DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff); +#endif +#ifdef HAVE_PNG +DECLARE_IMAGE_INSTANTIATOR_FORMAT (png); +#endif +#ifdef HAVE_GIF +DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif); +#endif +#ifdef HAVE_XPM +DEFINE_DEVICE_IIFORMAT (mswindows, xpm); +#endif +DEFINE_DEVICE_IIFORMAT (mswindows, xbm); +#ifdef HAVE_XFACE +DEFINE_DEVICE_IIFORMAT (mswindows, xface); +#endif +DEFINE_DEVICE_IIFORMAT (mswindows, button); +DEFINE_DEVICE_IIFORMAT (mswindows, edit_field); +DEFINE_DEVICE_IIFORMAT (mswindows, subwindow); +DEFINE_DEVICE_IIFORMAT (mswindows, widget); +DEFINE_DEVICE_IIFORMAT (mswindows, label); +DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar); +DEFINE_DEVICE_IIFORMAT (mswindows, combo_box); +DEFINE_DEVICE_IIFORMAT (mswindows, progress_gauge); +DEFINE_DEVICE_IIFORMAT (mswindows, tree_view); +DEFINE_DEVICE_IIFORMAT (mswindows, tab_control); DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp); Lisp_Object Qbmp; @@ -58,7 +99,8 @@ Lisp_Object Qmswindows_resource; static void mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, - enum image_instance_type type); + int slices, + enum image_instance_type type); static void mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, struct frame* f); @@ -87,9 +129,9 @@ static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device, if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0) { int bpline = BPLINE(width * 3); - /* FIXME: we can do this because 24bpp implies no colour table, once - * we start paletizing this is no longer true. The X versions of - * this function quantises to 256 colours or bit masks down to a + /* FIXME: we can do this because 24bpp implies no color table, once + * we start palettizing this is no longer true. The X versions of + * this function quantises to 256 colors or bit masks down to a * long. Windows can actually handle rgb triples in the raw so I * don't see much point trying to optimize down to the best * structure - unless it has memory / color allocation implications @@ -222,13 +264,13 @@ mswindows_locate_pixmap_file (Lisp_Object name) return Qnil; } - if (locate_file (Vmswindows_bitmap_file_path, name, "", &found, R_OK) < 0) + if (locate_file (Vmswindows_bitmap_file_path, name, Qnil, &found, R_OK) < 0) { Lisp_Object temp = list1 (Vdata_directory); struct gcpro gcpro1; GCPRO1 (temp); - locate_file (temp, name, "", &found, R_OK); + locate_file (temp, name, Qnil, &found, R_OK); UNGCPRO; } @@ -249,6 +291,7 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, int dest_mask, void *bmp_data, int bmp_bits, + int slices, Lisp_Object instantiator, int x_hot, int y_hot, int create_mask) @@ -257,7 +300,7 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, struct device *d = XDEVICE (device); struct frame *f; void* bmp_buf=0; - int type; + int type = 0; HBITMAP bitmap; HDC hdc; @@ -290,12 +333,14 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, /* copy in the actual bitmap */ memcpy (bmp_buf, bmp_data, bmp_bits); - mswindows_initialize_dibitmap_image_instance (ii, type); + mswindows_initialize_dibitmap_image_instance (ii, slices, type); IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = find_keyword_in_vector (instantiator, Q_file); + /* Fixup a set of bitmaps. */ 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; @@ -315,8 +360,36 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, } static void +image_instance_add_dibitmap (struct 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)); + void* bmp_buf=0; + HDC hdc = FRAME_MSWINDOWS_CDC (f); + HBITMAP bitmap = CreateDIBSection (hdc, + bmp_info, + DIB_RGB_COLORS, + &bmp_buf, + 0,0); + + if (!bitmap || !bmp_buf) + signal_simple_error ("Unable to create bitmap", instantiator); + + /* copy in the actual bitmap */ + memcpy (bmp_buf, bmp_data, bmp_bits); + IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (ii, slice) = bitmap; +} + +static void mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, int width, int height, + int slices, unsigned char *eimage, int dest_mask, Lisp_Object instantiator, @@ -327,6 +400,7 @@ mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, unsigned char* bmp_data; int bmp_bits; COLORREF bkcolor; + int slice; if (!DEVICE_MSWINDOWS_P (XDEVICE (device))) signal_simple_error ("Not an mswindows device", device); @@ -336,21 +410,29 @@ mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain))); - /* build a bitmap from the eimage */ - if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage, - &bmp_bits, &bmp_data))) + for (slice = 0; slice < slices; slice++) { - signal_simple_error ("EImage to DIBitmap conversion failed", - instantiator); - } - - /* Now create the pixmap and set up the image instance */ - init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, - bmp_data, bmp_bits, instantiator, - 0, 0, 0); + /* build a bitmap from the eimage */ + if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, + eimage + (width * height * 3 * slice), + &bmp_bits, &bmp_data))) + { + signal_simple_error ("EImage to DIBitmap conversion failed", + instantiator); + } - xfree (bmp_info); - xfree (bmp_data); + /* Now create the pixmap and set up the image instance */ + if (slice == 0) + init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, + bmp_data, bmp_bits, slices, instantiator, + 0, 0, 0); + else + image_instance_add_dibitmap (ii, bmp_info, bmp_data, bmp_bits, slice, + instantiator); + + xfree (bmp_info); + xfree (bmp_data); + } } static void set_mono_pixel ( unsigned char* bits, @@ -521,6 +603,8 @@ mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii, IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), SRCCOPY)) { + DeleteObject (newbmp); + DeleteDC (hdcDst); return 0; } @@ -553,6 +637,8 @@ mswindows_create_resized_mask (struct Lisp_Image_Instance* ii, IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), SRCCOPY)) { + DeleteObject (newmask); + DeleteDC (hdcDst); return NULL; } @@ -656,7 +742,8 @@ extract_xpm_color_names (Lisp_Object device, colortbl[j].color = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons))); - colortbl[j].name = (char *) XSTRING_DATA (XCAR (cons)); + GET_C_STRING_OS_DATA_ALLOCA (XCAR (cons), colortbl[j].name); + colortbl[j].name = xstrdup (colortbl[j].name); /* mustn't lose this when we return */ free_cons (XCONS (cons)); cons = results; results = XCDR (results); @@ -695,7 +782,7 @@ static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer, break; case XpmFileInvalid: { - signal_simple_error ("invalid XPM data", image); + signal_simple_error ("Invalid XPM data", image); } case XpmNoMemory: { @@ -855,7 +942,13 @@ mswindows_xpm_instantiate (Lisp_Object image_instance, } if (color_symbols) - xfree(color_symbols); + { + while (nsymbols--) + { + xfree (color_symbols[nsymbols].name); + } + xfree(color_symbols); + } /* build a bitmap from the eimage */ if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage, @@ -868,7 +961,7 @@ mswindows_xpm_instantiate (Lisp_Object image_instance, /* Now create the pixmap and set up the image instance */ init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, - bmp_data, bmp_bits, instantiator, + bmp_data, bmp_bits, 1, instantiator, x_hot, y_hot, transp); xfree (bmp_info); @@ -931,7 +1024,7 @@ bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, /* Now create the pixmap and set up the image instance */ init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, - bmp_data, bmp_bits, instantiator, + bmp_data, bmp_bits, 1, instantiator, 0, 0, 0); } @@ -1037,7 +1130,7 @@ static CONST resource_t bitmap_table[] = { "size", OBM_SIZE }, { "btsize", OBM_BTSIZE }, { "check", OBM_CHECK }, - { "cehckboxes", OBM_CHECKBOXES }, + { "checkboxes", OBM_CHECKBOXES }, { "btncorners" , OBM_BTNCORNERS }, {0} }; @@ -1089,7 +1182,9 @@ static int resource_name_to_resource (Lisp_Object name, int type) } do { - if (!strcasecmp ((char*)res->name, XSTRING_DATA (name))) + Extbyte* nm=0; + GET_C_STRING_OS_DATA_ALLOCA (name, nm); + if (!strcasecmp ((char*)res->name, nm)) return res->resource_id; } while ((++res)->name); return 0; @@ -1147,11 +1242,12 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti /* mess with the keyword info we were provided with */ if (!NILP (file)) { + Extbyte* f=0; + GET_C_STRING_FILENAME_DATA_ALLOCA (file, f); #ifdef __CYGWIN32__ - CYGWIN_WIN32_PATH (XSTRING_DATA (file), fname); + CYGWIN_WIN32_PATH (f, fname); #else - /* #### FIXME someone who knows ... */ - fname = XSTRING_DATA (file); + fname = f; #endif if (NILP (resource_id)) @@ -1164,12 +1260,12 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti type)); if (!resid) - resid = XSTRING_DATA (resource_id); + GET_C_STRING_OS_DATA_ALLOCA (resource_id, resid); } } else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id, type)))) - signal_simple_error ("invalid resource identifier", resource_id); + signal_simple_error ("Invalid resource identifier", resource_id); /* load the image */ if (!(himage = LoadImage (hinst, resid, type, 0, 0, @@ -1177,13 +1273,13 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti LR_SHARED | (!NILP (file) ? LR_LOADFROMFILE : 0)))) { - signal_simple_error ("cannot load image", instantiator); + signal_simple_error ("Cannot load image", instantiator); } if (hinst) FreeLibrary (hinst); - mswindows_initialize_dibitmap_image_instance (ii, iitype); + mswindows_initialize_dibitmap_image_instance (ii, 1, iitype); IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file; IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = @@ -1291,7 +1387,7 @@ in this Software without prior written authorization from the X Consortium. /* - * Based on an optimized version provided by Jim Becker, Auguest 5, 1988. + * Based on an optimized version provided by Jim Becker, August 5, 1988. */ #ifndef BitmapSuccess #define BitmapSuccess 0 @@ -1536,7 +1632,7 @@ xbm_create_bitmap_from_data (HDC hdc, char *data, int mask, COLORREF fg, COLORREF bg) { int old_width = (width + 7)/8; - int new_width = 2*((width + 15)/16); + int new_width = BPLINE (2*((width + 15)/16)); unsigned char *offset; void *bmp_buf = 0; unsigned char *new_data, *new_offset; @@ -1548,7 +1644,7 @@ xbm_create_bitmap_from_data (HDC hdc, char *data, if (!bmp_info) return NULL; - new_data = (unsigned char *) xmalloc (height * new_width); + new_data = (unsigned char *) xmalloc_and_zero (height * new_width); if (!new_data) { @@ -1561,8 +1657,6 @@ xbm_create_bitmap_from_data (HDC hdc, char *data, offset = data + i*old_width; new_offset = new_data + i*new_width; - new_offset[new_width - 1] = 0; /* there may be an extra byte - that needs to be padded */ for (j=0; jbmiHeader.biWidth=width; - bmp_info->bmiHeader.biHeight=-height; + bmp_info->bmiHeader.biHeight=-(LONG)height; bmp_info->bmiHeader.biPlanes=1; bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmp_info->bmiHeader.biBitCount=1; @@ -1667,7 +1761,7 @@ init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii, IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); - mswindows_initialize_dibitmap_image_instance (ii, type); + mswindows_initialize_dibitmap_image_instance (ii, 1, type); IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = find_keyword_in_vector (instantiator, Q_file); @@ -1728,10 +1822,10 @@ init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii, if (NILP (background)) background = pointer_bg; - XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), - find_keyword_in_vector (instantiator, Q_hotspot_x)); - XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), - find_keyword_in_vector (instantiator, Q_hotspot_y)); + IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = + find_keyword_in_vector (instantiator, Q_hotspot_x); + IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = + find_keyword_in_vector (instantiator, Q_hotspot_y); IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground; IMAGE_INSTANCE_PIXMAP_BG (ii) = background; if (COLOR_INSTANCEP (foreground)) @@ -1807,6 +1901,93 @@ mswindows_xbm_instantiate (Lisp_Object image_instance, XINT (XCAR (XCDR (data))), gcc_go_home); } +#ifdef HAVE_XFACE +/********************************************************************** + * X-Face * + **********************************************************************/ +#if defined(EXTERN) +/* This is about to get redefined! */ +#undef EXTERN +#endif +/* We have to define SYSV32 so that compface.h includes string.h + instead of strings.h. */ +#define SYSV32 +#ifdef __cplusplus +extern "C" { +#endif +#include +#ifdef __cplusplus +} +#endif +/* JMP_BUF cannot be used here because if it doesn't get defined + to jmp_buf we end up with a conflicting type error with the + definition in compface.h */ +extern jmp_buf comp_env; +#undef SYSV32 + +static void +mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + 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; + + assert (!NILP (data)); + + GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring); + + if ((p = strchr (dstring, ':'))) + { + dstring = p + 1; + } + + /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */ + if (!(stattis = setjmp (comp_env))) + { + UnCompAll ((char *) dstring); + UnGenFace (); + } + + switch (stattis) + { + case -2: + emsg = "uncompface: internal error"; + break; + case -1: + emsg = "uncompface: insufficient or invalid data"; + break; + case 1: + emsg = "uncompface: excess data ignored"; + break; + } + + if (emsg) + signal_simple_error_2 (emsg, data, Qimage); + + bp = bits = (char *) alloca (PIXELS / 8); + + /* the compface library exports char F[], which uses a single byte per + pixel to represent a 48x48 bitmap. Yuck. */ + for (i = 0, p = F; i < (PIXELS / 8); ++i) + { + int n, b; + /* reverse the bit order of each byte... */ + for (b = n = 0; b < 8; ++b) + { + n |= ((*p++) << b); + } + *bp++ = (char) n; + } + + xbm_instantiate_1 (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, 48, 48, bits); +} +#endif /* HAVE_XFACE */ + /************************************************************************/ /* image instance methods */ @@ -1835,32 +2016,235 @@ mswindows_print_image_instance (struct Lisp_Image_Instance *p, } write_c_string (")", printcharfun); break; + default: break; } } +#ifdef DEBUG_WIDGETS +extern int debug_widget_instances; +#endif + static void mswindows_finalize_image_instance (struct Lisp_Image_Instance *p) { - if (!p->data) - return; - if (DEVICE_LIVE_P (XDEVICE (p->device))) { - if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)) - DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)); - IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0; - if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) - DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p)); - IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0; - if (IMAGE_INSTANCE_MSWINDOWS_ICON (p)) - DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p)); - IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0; + if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET + || + IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) + { +#ifdef DEBUG_WIDGETS + debug_widget_instances--; + stderr_out ("widget destroyed, %d left\n", debug_widget_instances); +#endif + if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) + { + DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p)); + DestroyWindow (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)); + IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0; + } + } + else if (p->data) + { + int i; + if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)) + disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)); + + if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p)) + { + for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++) + { + if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i)) + DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i)); + IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i) = 0; + } + xfree (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p)); + IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p) = 0; + } + if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) + DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p)); + IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0; + if (IMAGE_INSTANCE_MSWINDOWS_ICON (p)) + DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p)); + IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0; + } + } + + if (p->data) + { + xfree (p->data); + p->data = 0; + } +} + +/************************************************************************/ +/* subwindow and widget support */ +/************************************************************************/ + +/* 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) +{ + if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) + { + SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), + NULL, + 0, 0, 0, 0, + SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE + | SWP_NOSENDCHANGING); } +} - xfree (p->data); - p->data = 0; +/* 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, + struct display_glyph_area* dga) +{ + /* move the window before mapping it ... */ + SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), + NULL, + x, y, dga->width, dga->height, + SWP_NOZORDER + | SWP_NOCOPYBITS | SWP_NOSENDCHANGING); + /* ... adjust the child ... */ + SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), + NULL, + -dga->xoffset, -dga->yoffset, 0, 0, + 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); +} + +/* resize the subwindow instance */ +static void +mswindows_resize_subwindow (struct 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); +} + +/* 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) +{ + if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) + { + /* 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))), + MAKELPARAM (TRUE, 0)); + } +} + +/* register widgets into our hastable 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) +{ + Lisp_Object frame = FW_FRAME (domain); + struct frame* f = XFRAME (frame); + int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f), + gui, + WIDGET_GLYPH_SLOT); + Fputhash (make_int (id), + XGUI_ITEM (gui)->callback, + FRAME_MSWINDOWS_WIDGET_HASH_TABLE (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), + domain); +} + +static void +mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + struct 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); + HWND wnd; + + if (!DEVICE_MSWINDOWS_P (d)) + signal_simple_error ("Not an mswindows device", device); + + /* have to set the type this late in case there is no device + instantiation for a widget */ + IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW; + /* Allocate space for the clip window */ + ii->data = xnew_and_zero (struct mswindows_subwindow_data); + + if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii) + = CreateWindowEx( + 0, /* EX flags */ + XEMACS_CONTROL_CLASS, + 0, /* text */ + WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD, + 0, /* starting x position */ + 0, /* starting y position */ + IMAGE_INSTANCE_WIDGET_WIDTH (ii), + IMAGE_INSTANCE_WIDGET_HEIGHT (ii), + /* parent window */ + FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), + NULL, /* No menu */ + NULL, /* must be null for this class */ + NULL)) == NULL) + signal_simple_error ("window creation failed with code", + make_int (GetLastError())); + + wnd = CreateWindow( "STATIC", + "", + WS_CHILD, + 0, /* starting x position */ + 0, /* starting y position */ + IMAGE_INSTANCE_WIDGET_WIDTH (ii), + IMAGE_INSTANCE_WIDGET_HEIGHT (ii), + IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii), + 0, + (HINSTANCE) + GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), + GWL_HINSTANCE), + NULL); + + SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance)); + IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd; } static int @@ -1876,6 +2260,7 @@ mswindows_image_instance_equal (struct Lisp_Image_Instance *p1, != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2)) return 0; break; + default: break; } @@ -1892,6 +2277,7 @@ mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth) case IMAGE_COLOR_PIXMAP: case IMAGE_POINTER: return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p); + default: return 0; } @@ -1905,7 +2291,8 @@ mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth) static void mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, - enum image_instance_type type) + int slices, + enum image_instance_type type) { ii->data = xnew_and_zero (struct mswindows_image_instance_data); IMAGE_INSTANCE_TYPE (ii) = type; @@ -1915,9 +2302,570 @@ mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil; IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil; IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil; + IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices; + IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (ii) = + xnew_array_and_zero (HBITMAP, slices); } +#ifdef HAVE_WIDGETS + +/************************************************************************/ +/* widgets */ +/************************************************************************/ +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) +{ + /* this function can call lisp */ + struct 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); + Extbyte* nm=0; + HWND wnd; + int id = 0xffff; + Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); + struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui); + + if (!DEVICE_MSWINDOWS_P (d)) + signal_simple_error ("Not an mswindows device", device); + + if (!gui_item_active_p (gui)) + flags |= WS_DISABLED; + + style = pgui->style; + + if (!NILP (pgui->callback)) + { + 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); + + /* 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 */ + XEMACS_CONTROL_CLASS, + 0, /* text */ + WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD, + 0, /* starting x position */ + 0, /* starting y position */ + IMAGE_INSTANCE_WIDGET_WIDTH (ii), + IMAGE_INSTANCE_WIDGET_HEIGHT (ii), + /* parent window */ + FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), + (HMENU)id, /* No menu */ + NULL, /* must be null for this class */ + NULL)) == NULL) + signal_simple_error ("window creation failed with code", + make_int (GetLastError())); + + if ((wnd = CreateWindowEx( + exflags /* | WS_EX_NOPARENTNOTIFY*/, + class, + nm, + flags | WS_CHILD | WS_VISIBLE, + 0, /* starting x position */ + 0, /* starting y position */ + IMAGE_INSTANCE_WIDGET_WIDTH (ii), + IMAGE_INSTANCE_WIDGET_HEIGHT (ii), + /* parent window */ + IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii), + (HMENU)id, /* No menu */ + (HINSTANCE) + GetWindowLong + (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), + GWL_HINSTANCE), + NULL)) == NULL) + signal_simple_error ("window creation failed with code", + make_int (GetLastError())); + + 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)); +} + +/* 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 + many-to-one relationship with things you see, whereas widgets can + only be one-to-one (i.e. per frame) */ +static void +mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + 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); + HWND wnd; + int flags = BS_NOTIFY; + Lisp_Object style; + Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); + struct 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)) + glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1); + + if (IMAGE_INSTANCEP (glyph)) + flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ? + BS_BITMAP : BS_ICON; + } + + style = pgui->style; + + if (EQ (style, Qradio)) + { + flags |= BS_RADIOBUTTON; + } + else if (EQ (style, Qtoggle)) + { + flags |= BS_AUTOCHECKBOX; + } + else + flags |= BS_DEFPUSHBUTTON; + + mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, "BUTTON", flags, + WS_EX_CONTROLPARENT); + + wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); + /* set the checked state */ + if (gui_item_selected_p (gui)) + SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); + else + SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); + /* add the image if one was given */ + if (!NILP (glyph) && IMAGE_INSTANCEP (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))); + } +} + +/* instantiate an edit control */ +static void +mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + 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); +} + +/* instantiate a progress gauge */ +static void +mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + HWND wnd; + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + 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); + wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); + /* set the colors */ +#ifdef PBS_SETBKCOLOR + SendMessage (wnd, PBS_SETBKCOLOR, 0, + (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR + (XCOLOR_INSTANCE + (FACE_BACKGROUND + (XIMAGE_INSTANCE_WIDGET_FACE (ii), + XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))))); +#endif +#ifdef PBS_SETBARCOLOR + SendMessage (wnd, PBS_SETBARCOLOR, 0, + (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR + (XCOLOR_INSTANCE + (FACE_FOREGROUND + (XIMAGE_INSTANCE_WIDGET_FACE (ii), + XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))))); +#endif +} + +/* instantiate a tree view widget */ +static HTREEITEM add_tree_item (Lisp_Object image_instance, + HWND wnd, HTREEITEM parent, Lisp_Object item, + int children, Lisp_Object domain) +{ + TV_INSERTSTRUCT tvitem; + HTREEITEM ret; + + tvitem.hParent = parent; + tvitem.hInsertAfter = TVI_LAST; + tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN; + tvitem.item.cChildren = children; + + if (GUI_ITEMP (item)) + { + tvitem.item.lParam = mswindows_register_gui_item (item, domain); + tvitem.item.mask |= TVIF_PARAM; + GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name, + tvitem.item.pszText); + } + else + GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.item.pszText); + + tvitem.item.cchTextMax = strlen (tvitem.item.pszText); + + if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM, + 0, (LPARAM)&tvitem)) == 0) + signal_simple_error ("error adding tree view entry", item); + + return ret; +} + +static void add_tree_item_list (Lisp_Object image_instance, + HWND wnd, HTREEITEM parent, Lisp_Object list, + Lisp_Object domain) +{ + Lisp_Object rest; + + /* get the first item */ + parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain); + /* recursively add items to the tree view */ + LIST_LOOP (rest, XCDR (list)) + { + if (LISTP (XCAR (rest))) + add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain); + else + add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain); + } +} + +static void +mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + Lisp_Object rest; + HWND wnd; + HTREEITEM parent; + struct 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); + + wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); + + /* define a root */ + parent = add_tree_item (image_instance, wnd, NULL, + XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)), + TRUE, domain); + + /* recursively add items to the tree view */ + /* add items to the tab */ + LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) + { + if (LISTP (XCAR (rest))) + add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain); + else + add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain); + } +} + +/* instantiate a tab control */ +static TC_ITEM* add_tab_item (Lisp_Object image_instance, + HWND wnd, Lisp_Object item, + Lisp_Object domain, int index) +{ + TC_ITEM tvitem, *ret; + + tvitem.mask = TCIF_TEXT; + + if (GUI_ITEMP (item)) + { + tvitem.lParam = mswindows_register_gui_item (item, domain); + tvitem.mask |= TCIF_PARAM; + GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name, + tvitem.pszText); + } + else + { + CHECK_STRING (item); + GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.pszText); + } + + tvitem.cchTextMax = strlen (tvitem.pszText); + + if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM, + index, (LPARAM)&tvitem)) < 0) + signal_simple_error ("error adding tab entry", item); + + return ret; +} + +static void +mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + Lisp_Object rest; + HWND wnd; + int index = 0; + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + 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); + + 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++; + } +} + +/* 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) +{ + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + + if (EQ (prop, Q_items)) + { + HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); + int index = 0; + Lisp_Object rest; + check_valid_item_list_1 (val); + + /* delete the pre-existing items */ + SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0); + + 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))) + { + add_tab_item (image_instance, wnd, XCAR (rest), + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii), index); + index++; + } + + return Qt; + } + return Qunbound; +} + +/* instantiate a static control possible for putting other things in */ +static void +mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, "STATIC", + 0, WS_EX_STATICEDGE); +} + +/* instantiate a scrollbar control */ +static void +mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, "SCROLLBAR", + 0, + WS_EX_CLIENTEDGE ); +} + +/* instantiate a combo control */ +static void +mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + 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_Object rest; + Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties), + Q_items, Qnil); + int len; + GET_LIST_LENGTH (data, len); + + /* Maybe ought to generalise this more but it may be very windows + specific. In windows the window height of a combo box is the + height when the combo box is open. Thus we need to set the height + 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); + + 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); + 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)) + { + Extbyte* lparam; + GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), lparam); + if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR) + signal_simple_error ("error adding combo entries", instantiator); + } +} + +/* get properties of a control */ +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); + /* get the text from a control */ + if (EQ (prop, Q_text)) + { + Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0); + Extbyte* buf =alloca (len+1); + + SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf); + return build_ext_string (buf, FORMAT_OS); + } + return Qunbound; +} + +/* get properties of a button */ +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); + /* check the state of a button */ + if (EQ (prop, Q_selected)) + { + if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED) + return Qt; + else + return Qnil; + } + return Qunbound; +} + +/* get properties of a combo box */ +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); + /* 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); + 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 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) +{ + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + + if (EQ (prop, Q_percent)) + { + 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, + WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_NOTIFY: + case WM_COMMAND: + case WM_CTLCOLORBTN: + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLOREDIT: + case WM_CTLCOLORSTATIC: + case WM_CTLCOLORSCROLLBAR: + + return mswindows_wnd_proc (GetParent (hwnd), message, wParam, lParam); + default: + return DefWindowProc (hwnd, message, wParam, lParam); + } +} + +#endif /* HAVE_WIDGETS */ + + /************************************************************************/ /* initialization */ /************************************************************************/ @@ -1936,23 +2884,93 @@ console_type_create_glyphs_mswindows (void) 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, 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); -#ifdef HAVE_XPM - CONSOLE_HAS_METHOD (mswindows, xpm_instantiate); -#endif - CONSOLE_HAS_METHOD (mswindows, xbm_instantiate); + CONSOLE_HAS_METHOD (mswindows, resize_subwindow); } 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); /* image-instantiator types */ - +#ifdef HAVE_XPM + INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm); + IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate); +#endif + INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm); + IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate); +#ifdef HAVE_XFACE + INITIALIZE_DEVICE_IIFORMAT (mswindows, xface); + IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate); +#endif +#ifdef HAVE_JPEG + IIFORMAT_VALID_CONSOLE (mswindows, jpeg); +#endif +#ifdef HAVE_TIFF + IIFORMAT_VALID_CONSOLE (mswindows, tiff); +#endif +#ifdef HAVE_PNG + IIFORMAT_VALID_CONSOLE (mswindows, png); +#endif +#ifdef HAVE_GIF + IIFORMAT_VALID_CONSOLE (mswindows, gif); +#endif +#ifdef HAVE_WIDGETS + /* button widget */ + INITIALIZE_DEVICE_IIFORMAT (mswindows, button); + IIFORMAT_HAS_DEVMETHOD (mswindows, button, property); + IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate); + + INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field); + IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate); + + 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, instantiate); + + /* tree view widget */ + INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view); + /* IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);*/ + IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate); + + /* tab control widget */ + INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control); + IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate); + IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, set_property); +#endif + /* windows bitmap format */ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp"); - IIFORMAT_HAS_METHOD (bmp, validate); IIFORMAT_HAS_METHOD (bmp, normalize); IIFORMAT_HAS_METHOD (bmp, possible_dest_types); @@ -1960,7 +2978,9 @@ 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); + /* mswindows resources */ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource, "mswindows-resource"); @@ -1973,13 +2993,12 @@ 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); } void vars_of_glyphs_mswindows (void) { - Fprovide (Qbmp); - Fprovide (Qmswindows_resource); DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /* A list of the directories in which mswindows bitmap files may be found. This is used by the `make-image-instance' function.