Mercurial > hg > xemacs-beta
comparison src/redisplay-x.c @ 284:558f606b08ae r21-0b40
Import from CVS: tag r21-0b40
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:34:13 +0200 |
parents | c42ec1d1cded |
children | 341dac730539 |
comparison
equal
deleted
inserted
replaced
283:fa3d41851a08 | 284:558f606b08ae |
---|---|
50 #ifdef MULE | 50 #ifdef MULE |
51 #include "mule-ccl.h" | 51 #include "mule-ccl.h" |
52 #include "file-coding.h" /* for CCL conversion */ | 52 #include "file-coding.h" /* for CCL conversion */ |
53 #endif | 53 #endif |
54 | 54 |
55 /* X_DIVIDER_LINE_WIDTH is the width of the line drawn in the gutter. | |
56 X_DIVIDER_SPACING is the amount of blank space on each side of the line. | |
57 X_DIVIDER_WIDTH = X_DIVIDER_LINE_WIDTH + 2*X_DIVIDER_SPACING | |
58 */ | |
59 | |
60 /* Number of pixels below each line. */ | 55 /* Number of pixels below each line. */ |
61 /* #### implement me */ | 56 /* #### implement me */ |
62 int x_interline_space; | 57 int x_interline_space; |
63 | |
64 #define X_DIVIDER_LINE_WIDTH 3 | |
65 #define X_DIVIDER_SPACING 2 | |
66 #define X_DIVIDER_WIDTH (X_DIVIDER_LINE_WIDTH + 2 * X_DIVIDER_SPACING) | |
67 | 58 |
68 #define EOL_CURSOR_WIDTH 5 | 59 #define EOL_CURSOR_WIDTH 5 |
69 | 60 |
70 static void x_output_pixmap (struct window *w, struct display_line *dl, | 61 static void x_output_pixmap (struct window *w, struct display_line *dl, |
71 Lisp_Object image_instance, int xpos, | 62 Lisp_Object image_instance, int xpos, |
274 width_so_far += x_text_width_single_run (cachel, runs + i); | 265 width_so_far += x_text_width_single_run (cachel, runs + i); |
275 | 266 |
276 return width_so_far; | 267 return width_so_far; |
277 } | 268 } |
278 | 269 |
279 | |
280 /***************************************************************************** | |
281 x_divider_width | |
282 | |
283 Return the width of the vertical divider. This is a function because | |
284 divider_width is a device method. | |
285 ****************************************************************************/ | |
286 static int | |
287 x_divider_width (void) | |
288 { | |
289 return X_DIVIDER_WIDTH; | |
290 } | |
291 | |
292 /***************************************************************************** | 270 /***************************************************************************** |
293 x_divider_height | 271 x_divider_height |
294 | 272 |
295 Return the height of the horizontal divider. This is a function because | 273 Return the height of the horizontal divider. This is a function because |
296 divider_height is a device method. | 274 divider_height is a device method. |
1386 } | 1364 } |
1387 | 1365 |
1388 /***************************************************************************** | 1366 /***************************************************************************** |
1389 x_output_vertical_divider | 1367 x_output_vertical_divider |
1390 | 1368 |
1391 Draw a vertical divider down the left side of the given window. | 1369 Draw a vertical divider down the right side of the given window. |
1392 ****************************************************************************/ | 1370 ****************************************************************************/ |
1393 static void | 1371 static void |
1394 x_output_vertical_divider (struct window *w, int clear) | 1372 x_output_vertical_divider (struct window *w, int clear) |
1395 { | 1373 { |
1396 struct frame *f = XFRAME (w->frame); | 1374 struct frame *f = XFRAME (w->frame); |
1397 struct device *d = XDEVICE (f->device); | 1375 struct device *d = XDEVICE (f->device); |
1398 | 1376 |
1377 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); | |
1399 Display *dpy = DEVICE_X_DISPLAY (d); | 1378 Display *dpy = DEVICE_X_DISPLAY (d); |
1400 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1379 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1401 GC gc; | 1380 Pixel top_shadow_pixel, bottom_shadow_pixel, background_pixel; |
1402 | 1381 Lisp_Object tmp_pixel; |
1403 /* We don't use the normal gutter measurements here because the | 1382 XColor tmp_color; |
1404 horizontal scrollbars and toolbars do not stretch completely over | 1383 XGCValues gcv; |
1405 to the right edge of the window. Only the modeline does. */ | 1384 GC top_shadow_gc, bottom_shadow_gc, background_gc; |
1406 int modeline_height = window_modeline_height (w); | 1385 |
1407 int x1, x2; | 1386 int use_pixmap = 0; |
1408 int y1, y2; | 1387 int flip_gcs = 0; |
1409 | 1388 unsigned long mask; |
1410 #ifdef HAVE_SCROLLBARS | 1389 int x, y1, y2, width, shadow_thickness, spacing, line_width; |
1411 if (!NILP (w->scrollbar_on_left_p)) | 1390 face_index div_face = get_builtin_face_cache_index (w, Vvertical_divider_face); |
1412 #endif | 1391 |
1413 x1 = WINDOW_LEFT (w); | 1392 width = window_divider_width (w); |
1414 #ifdef HAVE_SCROLLBARS | 1393 shadow_thickness = XINT (w->vertical_divider_shadow_thickness); |
1394 spacing = XINT (w->vertical_divider_spacing); | |
1395 line_width = XINT (w->vertical_divider_line_width); | |
1396 x = WINDOW_RIGHT (w) - width; | |
1397 y1 = WINDOW_TOP (w); | |
1398 y2 = WINDOW_BOTTOM (w); | |
1399 | |
1400 memset (&gcv, ~0, sizeof (XGCValues)); | |
1401 | |
1402 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, div_face); | |
1403 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | |
1404 | |
1405 /* First, get the GC's. */ | |
1406 top_shadow_pixel = tmp_color.pixel; | |
1407 bottom_shadow_pixel = tmp_color.pixel; | |
1408 background_pixel = tmp_color.pixel; | |
1409 | |
1410 x_generate_shadow_pixels (f, &top_shadow_pixel, &bottom_shadow_pixel, | |
1411 background_pixel, ef->core.background_pixel); | |
1412 | |
1413 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, div_face); | |
1414 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | |
1415 gcv.background = tmp_color.pixel; | |
1416 gcv.graphics_exposures = False; | |
1417 mask = GCForeground | GCBackground | GCGraphicsExposures; | |
1418 | |
1419 /* If we can't distinguish one of the shadows (the color is the same as the | |
1420 background), it's better to use a pixmap to generate a dithrered gray. */ | |
1421 if (top_shadow_pixel == background_pixel || | |
1422 bottom_shadow_pixel == background_pixel) | |
1423 use_pixmap = 1; | |
1424 | |
1425 if (use_pixmap) | |
1426 { | |
1427 if (DEVICE_X_GRAY_PIXMAP (d) == None) | |
1428 { | |
1429 DEVICE_X_GRAY_PIXMAP (d) = | |
1430 XCreatePixmapFromBitmapData (dpy, x_win, (char *) gray_bits, | |
1431 gray_width, gray_height, 1, 0, 1); | |
1432 } | |
1433 | |
1434 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, div_face); | |
1435 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | |
1436 gcv.foreground = tmp_color.pixel; | |
1437 /* this is needed because the GC draws with a pixmap here */ | |
1438 gcv.fill_style = FillOpaqueStippled; | |
1439 gcv.stipple = DEVICE_X_GRAY_PIXMAP (d); | |
1440 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, | |
1441 (mask | GCStipple | GCFillStyle)); | |
1442 | |
1443 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, div_face); | |
1444 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | |
1445 bottom_shadow_pixel = tmp_color.pixel; | |
1446 | |
1447 flip_gcs = (bottom_shadow_pixel == | |
1448 WhitePixelOfScreen (DefaultScreenOfDisplay (dpy))); | |
1449 } | |
1415 else | 1450 else |
1416 x1 = WINDOW_RIGHT (w) - X_DIVIDER_WIDTH; | 1451 { |
1417 #endif | 1452 gcv.foreground = top_shadow_pixel; |
1418 x2 = x1 + X_DIVIDER_SPACING; | 1453 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); |
1419 | 1454 } |
1420 #ifdef HAVE_SCROLLBARS | 1455 |
1421 if (!NILP (w->scrollbar_on_top_p)) | 1456 gcv.foreground = bottom_shadow_pixel; |
1422 y1 = WINDOW_TOP (w); | 1457 bottom_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); |
1423 else | 1458 |
1424 #endif | 1459 if (use_pixmap && flip_gcs) |
1425 y1 = WINDOW_TEXT_TOP (w); | 1460 { |
1426 y2 = WINDOW_BOTTOM (w) - modeline_height; | 1461 GC tmp_gc = bottom_shadow_gc; |
1427 | 1462 bottom_shadow_gc = top_shadow_gc; |
1428 /* Draw the divider in the window. */ | 1463 top_shadow_gc = tmp_gc; |
1429 { | 1464 } |
1430 /* Clear the divider area first. This needs to be done when a | 1465 |
1431 window split occurs. */ | 1466 gcv.foreground = background_pixel; |
1432 if (clear) | 1467 background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); |
1433 XClearArea (dpy, x_win, x1, y1, X_DIVIDER_WIDTH, y2 - y1, False); | 1468 |
1434 | 1469 /* possibly revert the GC's in case the shadow thickness is < 0. |
1435 /* #### There needs to be some checks to make sure that whatever | 1470 This will give a depressed look to the divider */ |
1436 colors we choose, the line will be visible (not same color as | 1471 if (shadow_thickness < 0) |
1437 default background. | 1472 { |
1438 | 1473 GC temp; |
1439 #### No there don't. If I want the vertical divider to be | 1474 |
1440 invisible, I should be able to make it so. */ | 1475 temp = top_shadow_gc; |
1441 gc = x_get_gc (d, Qnil, WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX), | 1476 top_shadow_gc = bottom_shadow_gc; |
1442 WINDOW_FACE_CACHEL_FOREGROUND (w, MODELINE_INDEX), | 1477 bottom_shadow_gc = temp; |
1443 Qnil, Qnil); | 1478 |
1444 | 1479 /* better avoid a Bad Adress XLib error ;-) */ |
1445 /* Draw the divider line. */ | 1480 shadow_thickness = - shadow_thickness; |
1446 XFillRectangle (dpy, x_win, gc, x2, y1, X_DIVIDER_LINE_WIDTH, y2 - y1); | 1481 } |
1447 } | 1482 |
1448 | 1483 /* Clear the divider area first. This needs to be done when a |
1449 /* Draw the divider in the modeline but only if we are using 2D | 1484 window split occurs. */ |
1450 modelines. */ | 1485 if (clear) |
1451 if (EQ (Qzero, w->modeline_shadow_thickness)) | 1486 XClearArea (dpy, x_win, x, y1, width, y2 - y1, False); |
1452 { | 1487 |
1453 XFillRectangle (dpy, x_win, gc, x1, y2, X_DIVIDER_WIDTH, | 1488 /* Draw the divider line. */ |
1454 modeline_height); | 1489 XFillRectangle (dpy, x_win, background_gc, |
1455 | 1490 x + spacing + shadow_thickness, y1, |
1456 /* #### There needs to be some checks to make sure that whatever | 1491 line_width, y2 - y1); |
1457 colors we choose, the line will be visible (not same color as | 1492 |
1458 default background. */ | 1493 /* Draw the shadows around the divider line */ |
1459 gc = x_get_gc (d, Qnil, | 1494 x_output_shadows (f, x + spacing, y1, |
1460 WINDOW_FACE_CACHEL_FOREGROUND (w, MODELINE_INDEX), | 1495 width - 2 * spacing, y2 - y1, |
1461 WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX), | 1496 top_shadow_gc, bottom_shadow_gc, |
1462 Qnil, Qnil); | 1497 background_gc, shadow_thickness); |
1463 | |
1464 /* Draw the divider line. */ | |
1465 XFillRectangle (dpy, x_win, gc, x2, y2, X_DIVIDER_LINE_WIDTH, | |
1466 modeline_height); | |
1467 } | |
1468 } | 1498 } |
1469 | 1499 |
1470 /***************************************************************************** | 1500 /***************************************************************************** |
1471 x_output_blank | 1501 x_output_blank |
1472 | 1502 |
2292 console_type_create_redisplay_x (void) | 2322 console_type_create_redisplay_x (void) |
2293 { | 2323 { |
2294 /* redisplay methods */ | 2324 /* redisplay methods */ |
2295 CONSOLE_HAS_METHOD (x, text_width); | 2325 CONSOLE_HAS_METHOD (x, text_width); |
2296 CONSOLE_HAS_METHOD (x, output_display_block); | 2326 CONSOLE_HAS_METHOD (x, output_display_block); |
2297 CONSOLE_HAS_METHOD (x, divider_width); | |
2298 CONSOLE_HAS_METHOD (x, divider_height); | 2327 CONSOLE_HAS_METHOD (x, divider_height); |
2299 CONSOLE_HAS_METHOD (x, eol_cursor_width); | 2328 CONSOLE_HAS_METHOD (x, eol_cursor_width); |
2300 CONSOLE_HAS_METHOD (x, output_vertical_divider); | 2329 CONSOLE_HAS_METHOD (x, output_vertical_divider); |
2301 CONSOLE_HAS_METHOD (x, clear_to_window_end); | 2330 CONSOLE_HAS_METHOD (x, clear_to_window_end); |
2302 CONSOLE_HAS_METHOD (x, clear_region); | 2331 CONSOLE_HAS_METHOD (x, clear_region); |