comparison src/toolbar-msw.c @ 286:57709be46d1b r21-0b41

Import from CVS: tag r21-0b41
author cvs
date Mon, 13 Aug 2007 10:35:03 +0200
parents 558f606b08ae
children e11d67e05968
comparison
equal deleted inserted replaced
285:9a3756523c1b 286:57709be46d1b
38 #include "elhash.h" 38 #include "elhash.h"
39 #include "console-msw.h" 39 #include "console-msw.h"
40 #include "glyphs-msw.h" 40 #include "glyphs-msw.h"
41 #include "objects-msw.h" 41 #include "objects-msw.h"
42 42
43 /* Why did Kirill choose this range ? */
44 #define TOOLBAR_ITEM_ID_MIN 0x4000 43 #define TOOLBAR_ITEM_ID_MIN 0x4000
45 #define TOOLBAR_ITEM_ID_MAX 0x7FFF 44 #define TOOLBAR_ITEM_ID_MAX 0x7FFF
46 #define TOOLBAR_ITEM_ID_BITS(x) (((x) & 0x3FFF) | 0x4000) 45 #define TOOLBAR_ITEM_ID_BITS(x) (((x) & 0x3FFF) | 0x4000)
47 #define TOOLBAR_ID_BIAS 16 46 #define TOOLBAR_ID_BIAS 16
48 #define TOOLBAR_HANDLE(f,p) \ 47 #define TOOLBAR_HANDLE(f,p) \
148 x=0; 147 x=0;
149 148
150 window = FRAME_LAST_NONMINIBUF_WINDOW (f); 149 window = FRAME_LAST_NONMINIBUF_WINDOW (f);
151 w = XWINDOW (window); 150 w = XWINDOW (window);
152 151
153 toolbarwnd = TOOLBAR_HANDLE(f,pos); 152 toolbarwnd = TOOLBAR_HANDLE (f,pos);
154 153
155 /* set button sizes based on bar size */ 154 /* set button sizes based on bar size */
156 if (vert) 155 if (vert)
157 { 156 {
158 width = height = bar_width 157 width = height = bar_width
164 height = width = bar_height 163 height = width = bar_height
165 - (window_frame_width + shadow_thickness) * 2; 164 - (window_frame_width + shadow_thickness) * 2;
166 bmwidth = bmheight = width - (border_width + shadow_thickness) * 2; 165 bmwidth = bmheight = width - (border_width + shadow_thickness) * 2;
167 } 166 }
168 167
169 button = FRAME_TOOLBAR_DATA (f, pos)->toolbar_buttons; 168 button = FRAME_TOOLBAR_BUTTONS (f, pos);
170 169
171 /* First loop over all of the buttons to determine how many there 170 /* First loop over all of the buttons to determine how many there
172 are. This loop will also make sure that all instances are 171 are. This loop will also make sure that all instances are
173 instantiated so when we actually output them they will come up 172 instantiated so when we actually output them they will come up
174 immediately. */ 173 immediately. */
175 while (!NILP (button)) 174 while (!NILP (button))
176 { 175 {
176
177 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); 177 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
178 checksum = HASH3 (checksum, 178 checksum = HASH4 (checksum,
179 internal_hash (get_toolbar_button_glyph(w, tb), 0), 179 internal_hash (get_toolbar_button_glyph(w, tb), 0),
180 internal_hash (tb->callback, 0)); 180 internal_hash (tb->callback, 0),
181 width);
181 button = tb->next; 182 button = tb->next;
182 nbuttons++; 183 nbuttons++;
183 } 184 }
184 185
185 /* only rebuild if something has changed */ 186 /* only rebuild if something has changed */
190 191
191 FRAME_MSWINDOWS_TOOLBAR_CHECKSUM(f,pos)=checksum; 192 FRAME_MSWINDOWS_TOOLBAR_CHECKSUM(f,pos)=checksum;
192 193
193 /* build up the data required by win32 fns. */ 194 /* build up the data required by win32 fns. */
194 button_tbl = xnew_array_and_zero (TBBUTTON, nbuttons); 195 button_tbl = xnew_array_and_zero (TBBUTTON, nbuttons);
195 button = FRAME_TOOLBAR_DATA (f, pos)->toolbar_buttons; 196 button = FRAME_TOOLBAR_BUTTONS (f, pos);
196 tbbutton = button_tbl; 197 tbbutton = button_tbl;
197 198
198 while (!NILP (button)) 199 while (!NILP (button))
199 { 200 {
200 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); 201 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
202 HBITMAP bitmap=NULL, mask=NULL;
201 203
202 tbbutton->idCommand = allocate_toolbar_item_id (f, tb, pos); 204 tbbutton->idCommand = allocate_toolbar_item_id (f, tb, pos);
203 tbbutton->fsState=tb->enabled ? TBSTATE_ENABLED 205 tbbutton->fsState=tb->enabled ? TBSTATE_ENABLED
204 : TBSTATE_INDETERMINATE; 206 : TBSTATE_INDETERMINATE;
205 tbbutton->fsStyle=tb->blank ? TBSTYLE_SEP : TBSTYLE_BUTTON; 207 tbbutton->fsStyle=tb->blank ? TBSTYLE_SEP : TBSTYLE_BUTTON;
228 if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p)) 230 if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p))
229 { 231 {
230 /* we are going to honour the toolbar settings and 232 /* we are going to honour the toolbar settings and
231 resize the bitmaps accordingly */ 233 resize the bitmaps accordingly */
232 234
233 if (IMAGE_INSTANCE_PIXMAP_WIDTH (p) > bmwidth 235 if (IMAGE_INSTANCE_PIXMAP_WIDTH (p) != bmwidth
234 || 236 ||
235 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > bmheight) 237 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) != bmheight)
236 { 238 {
237 if (!mswindows_resize_dibitmap_instance 239 if (! (bitmap = mswindows_create_resized_bitmap
238 (p, f, bmwidth, bmheight)) 240 (p, f, bmwidth, bmheight)))
239 { 241 {
240 xfree (button_tbl); 242 xfree (button_tbl);
241 if (ilist) ImageList_Destroy (ilist); 243 if (ilist) ImageList_Destroy (ilist);
242 signal_simple_error ("couldn't resize pixmap", 244 signal_simple_error ("couldn't resize pixmap",
243 instance); 245 instance);
244 } 246 }
247 /* we don't care if the mask fails */
248 mask = mswindows_create_resized_mask
249 (p, f, bmwidth, bmheight);
245 } 250 }
246 else 251 else
247 { 252 {
248 bmwidth = IMAGE_INSTANCE_PIXMAP_WIDTH (p); 253 bmwidth = IMAGE_INSTANCE_PIXMAP_WIDTH (p);
249 bmheight = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); 254 bmheight = IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
250 } 255 }
251 256
252 /* need to build an image list for the bitmaps */ 257 /* need to build an image list for the bitmaps */
253 if (!ilist) 258 if (!ilist && !(ilist = ImageList_Create
259 ( bmwidth, bmheight,
260 ILC_COLOR24, nbuttons, nbuttons * 2 )))
254 { 261 {
255 if (!(ilist = ImageList_Create 262 xfree (button_tbl);
256 ( IMAGE_INSTANCE_PIXMAP_WIDTH (p), 263 signal_simple_error ("couldn't create image list",
257 IMAGE_INSTANCE_PIXMAP_HEIGHT (p), 264 instance);
258 ILC_COLOR24,
259 nbuttons,
260 nbuttons * 2 )))
261 {
262 xfree (button_tbl);
263 signal_simple_error ("couldn't create image list",
264 instance);
265 }
266 } 265 }
267 266
268 /* add a bitmap to the list */ 267 /* add a bitmap to the list */
269 if ((tbbutton->iBitmap = 268 if ((tbbutton->iBitmap =
270 ImageList_Add (ilist, 269 ImageList_Add (ilist, bitmap, mask)) < 0)
271 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p),
272 IMAGE_INSTANCE_MSWINDOWS_MASK (p))) < 0)
273 { 270 {
274 xfree (button_tbl); 271 xfree (button_tbl);
275 if (ilist) ImageList_Destroy (ilist); 272 if (ilist) ImageList_Destroy (ilist);
276 signal_simple_error ("image list creation failed", 273 signal_simple_error ("image list creation failed",
277 instance); 274 instance);
278 } 275 }
276 /* we're done with these now */
277 DeleteObject (bitmap);
278 DeleteObject (mask);
279 } 279 }
280 } 280 }
281 281
282 Fputhash (make_int (tbbutton->idCommand), 282 Fputhash (make_int (tbbutton->idCommand),
283 button, FRAME_MSWINDOWS_TOOLBAR_HASHTABLE (f)); 283 button, FRAME_MSWINDOWS_TOOLBAR_HASHTABLE (f));
284 284
285 tbbutton++; 285 tbbutton++;
286 button = tb->next; 286 button = tb->next;
287 } 287 }
288 288
289 button = FRAME_TOOLBAR_DATA (f, pos)->toolbar_buttons; 289 button = FRAME_TOOLBAR_BUTTONS (f, pos);
290 290
291 /* create the toolbar window? */ 291 /* create the toolbar window? */
292 if (!toolbarwnd 292 if (!toolbarwnd
293 && 293 &&
294 (toolbarwnd = 294 (toolbarwnd =
295 CreateWindowEx ( WS_EX_WINDOWEDGE, 295 CreateWindowEx ( WS_EX_WINDOWEDGE,
296 TOOLBARCLASSNAME, 296 TOOLBARCLASSNAME,
297 NULL, 297 NULL,
298 WS_CHILD | WS_VISIBLE | WS_DLGFRAME | TBSTYLE_TOOLTIPS 298 WS_CHILD | WS_VISIBLE | WS_DLGFRAME
299 | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER, 299 | TBSTYLE_TOOLTIPS | CCS_NORESIZE
300 | CCS_NOPARENTALIGN | CCS_NODIVIDER,
300 x, y, bar_width, bar_height, 301 x, y, bar_width, bar_height,
301 FRAME_MSWINDOWS_HANDLE (f), 302 FRAME_MSWINDOWS_HANDLE (f),
302 (HMENU)(TOOLBAR_ID_BIAS + pos), 303 (HMENU)(TOOLBAR_ID_BIAS + pos),
303 NULL, 304 NULL,
304 NULL))==NULL) 305 NULL))==NULL)
305 { 306 {
306 xfree (button_tbl); 307 xfree (button_tbl);
307 ImageList_Destroy (ilist); 308 ImageList_Destroy (ilist);
308 error ("couldn't create toolbar"); 309 error ("couldn't create toolbar");
309 } 310 }
311
310 #if 0 312 #if 0
311 SendMessage (toolbarwnd, TB_SETPADDING, 313 SendMessage (toolbarwnd, TB_SETPADDING,
312 0, MAKELPARAM(border_width, border_width)); 314 0, MAKELPARAM(border_width, border_width));
313 #endif 315 #endif
314 /* finally populate with images */ 316 /* finally populate with images */
320 } 322 }
321 323
322 /* set the size of buttons */ 324 /* set the size of buttons */
323 SendMessage (toolbarwnd, TB_SETBUTTONSIZE, 0, 325 SendMessage (toolbarwnd, TB_SETBUTTONSIZE, 0,
324 (LPARAM)MAKELONG (width, height)); 326 (LPARAM)MAKELONG (width, height));
325 327
326 /* set the size of bitmaps */ 328 /* set the size of bitmaps */
327 SendMessage (toolbarwnd, TB_SETBITMAPSIZE, 0, 329 SendMessage (toolbarwnd, TB_SETBITMAPSIZE, 0,
328 (LPARAM)MAKELONG (bmwidth, bmheight)); 330 (LPARAM)MAKELONG (bmwidth, bmheight));
331
332 /* tell it we've done it */
333 SendMessage (toolbarwnd, TB_AUTOSIZE, 0, 0);
329 334
330 /* finally populate with images */ 335 /* finally populate with images */
331 if (!SendMessage (toolbarwnd, TB_ADDBUTTONS, 336 if (!SendMessage (toolbarwnd, TB_ADDBUTTONS,
332 (WPARAM)nbuttons, (LPARAM)button_tbl)) 337 (WPARAM)nbuttons, (LPARAM)button_tbl))
333 { 338 {
383 by Windows and by XEmacs. */ 388 by Windows and by XEmacs. */
384 switch (pos) 389 switch (pos)
385 { 390 {
386 case TOP_TOOLBAR: 391 case TOP_TOOLBAR:
387 bar_x -= 2; bar_y--; 392 bar_x -= 2; bar_y--;
388 bar_width += 2; bar_height++; 393 bar_width++; bar_height++;
389 break; 394 break;
390 case LEFT_TOOLBAR: 395 case LEFT_TOOLBAR:
391 bar_x -= 2; bar_y--; 396 bar_x -= 2; bar_y--;
392 bar_width++; bar_height++; 397 bar_width++; bar_height++;
393 break; 398 break;
472 } 477 }
473 478
474 /* map toolbar hwnd to pos*/ 479 /* map toolbar hwnd to pos*/
475 int mswindows_find_toolbar_pos(struct frame* f, HWND ctrl) 480 int mswindows_find_toolbar_pos(struct frame* f, HWND ctrl)
476 { 481 {
477 #if 1
478 int id = GetDlgCtrlID(ctrl); 482 int id = GetDlgCtrlID(ctrl);
479 return id ? id - TOOLBAR_ID_BIAS : -1; 483 return id ? id - TOOLBAR_ID_BIAS : -1;
480 #else
481 if (GetDlgItem(FRAME_MSWINDOWS_HANDLE(f), TOOLBAR_ID_BIAS) == ctrl)
482 return 0;
483 else if (GetDlgItem(FRAME_MSWINDOWS_HANDLE(f), TOOLBAR_ID_BIAS +1) == ctrl)
484 return 1;
485 else if (GetDlgItem(FRAME_MSWINDOWS_HANDLE(f), TOOLBAR_ID_BIAS +2) == ctrl)
486 return 2;
487 else if (GetDlgItem(FRAME_MSWINDOWS_HANDLE(f), TOOLBAR_ID_BIAS +3) == ctrl)
488 return 3;
489 else
490 assert(0);
491 #endif
492 } 484 }
493 485
494 Lisp_Object 486 Lisp_Object
495 mswindows_get_toolbar_button_text ( struct frame* f, int command_id ) 487 mswindows_get_toolbar_button_text ( struct frame* f, int command_id )
496 { 488 {
513 */ 505 */
514 Lisp_Object 506 Lisp_Object
515 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id) 507 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id)
516 { 508 {
517 /* Try to map the command id through the proper hash table */ 509 /* Try to map the command id through the proper hash table */
518 Lisp_Object button, command, funcsym, frame; 510 Lisp_Object button, data, fn, arg, frame;
519 struct gcpro gcpro1; 511
520
521 button = Fgethash (make_int (id), 512 button = Fgethash (make_int (id),
522 FRAME_MSWINDOWS_TOOLBAR_HASHTABLE (f), Qnil); 513 FRAME_MSWINDOWS_TOOLBAR_HASHTABLE (f), Qnil);
523 514
524 if (NILP (button)) 515 if (NILP (button))
525 return Qnil; 516 return Qnil;
526 517
527 command = XTOOLBAR_BUTTON(button)->callback; 518 data = XTOOLBAR_BUTTON (button)->callback;
528 519
529 if (UNBOUNDP(command)) 520 /* #### ? */
521 if (UNBOUNDP (data))
530 return Qnil; 522 return Qnil;
531 523
532 /* Need to gcpro because the hashtable may get destroyed
533 by menu_cleanup(), and will not gcpro the command
534 any more */
535 GCPRO1 (command);
536
537 /* Ok, this is our one. Enqueue it. */ 524 /* Ok, this is our one. Enqueue it. */
538 if (SYMBOLP (command)) 525 get_callback (data, &fn, &arg);
539 funcsym = Qcall_interactively;
540 else if (CONSP (command))
541 funcsym = Qeval;
542 else
543 signal_simple_error ("Callback must be either evallable form or a symbol",
544 command);
545 526
546 XSETFRAME (frame, f); 527 XSETFRAME (frame, f);
547 enqueue_misc_user_event (frame, funcsym, command); 528 enqueue_misc_user_event (frame, fn, arg);
548 529
549 /* Needs good bump also, for WM_COMMAND may have been dispatched from 530 /* Needs good bump also, for WM_COMMAND may have been dispatched from
550 mswindows_need_event, which will block again despite new command 531 mswindows_need_event, which will block again despite new command
551 event has arrived */ 532 event has arrived */
552 mswindows_bump_queue (); 533 mswindows_bump_queue ();
553
554 UNGCPRO; /* command */
555 return Qt; 534 return Qt;
556 } 535 }
557 536
558 537
559 /************************************************************************/ 538 /************************************************************************/