diff options
| -rw-r--r-- | doc/emacs/ChangeLog | 4 | ||||
| -rw-r--r-- | doc/emacs/xresources.texi | 12 | ||||
| -rw-r--r-- | etc/NEWS | 3 | ||||
| -rw-r--r-- | lwlib/ChangeLog | 20 | ||||
| -rw-r--r-- | lwlib/lwlib-Xaw.c | 412 | ||||
| -rw-r--r-- | lwlib/lwlib-int.h | 6 | ||||
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/xmenu.c | 23 |
8 files changed, 436 insertions, 49 deletions
diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog index 8cb082d64e2..1fc36c5fcda 100644 --- a/doc/emacs/ChangeLog +++ b/doc/emacs/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2010-04-11 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * xresources.texi (Lucid Resources): Mention faceName for dialogs. | ||
| 4 | |||
| 1 | 2010-04-08 Jan Djärv <jan.h.d@swipnet.se> | 5 | 2010-04-08 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 6 | ||
| 3 | * xresources.texi (Lucid Resources): Mention faceName to set Xft fonts. | 7 | * xresources.texi (Lucid Resources): Mention faceName to set Xft fonts. |
diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi index 4e4f3ad87a2..bc60ff946af 100644 --- a/doc/emacs/xresources.texi +++ b/doc/emacs/xresources.texi | |||
| @@ -399,8 +399,9 @@ Italic flag for face @var{face}---instead of @code{attributeSlant}. | |||
| 399 | @end table | 399 | @end table |
| 400 | 400 | ||
| 401 | @node Lucid Resources | 401 | @node Lucid Resources |
| 402 | @appendixsec Lucid Menu X Resources | 402 | @appendixsec Lucid Menu And Dialog X Resources |
| 403 | @cindex Menu X Resources (Lucid widgets) | 403 | @cindex Menu X Resources (Lucid widgets) |
| 404 | @cindex Dialog X Resources (Lucid widgets) | ||
| 404 | @cindex Lucid Widget X Resources | 405 | @cindex Lucid Widget X Resources |
| 405 | 406 | ||
| 406 | @ifnottex | 407 | @ifnottex |
| @@ -434,12 +435,13 @@ Emacs.pane.menubar.faceName: Courier-12 | |||
| 434 | To specify a font, use fontconfig font names as values to the @code{faceName} | 435 | To specify a font, use fontconfig font names as values to the @code{faceName} |
| 435 | resource. | 436 | resource. |
| 436 | 437 | ||
| 437 | If Emacs is not built with the Xft library, Lucid menus can only display | 438 | If Emacs is not built with the Xft library, Lucid menus and dialogs can only |
| 438 | old style fonts. If Emacs is built with Xft and you prefer the old fonts, | 439 | display old style fonts. If Emacs is built with Xft and you prefer the old |
| 439 | you have to specify @samp{none} to @code{faceName}: | 440 | fonts, you have to specify @samp{none} to @code{faceName}: |
| 440 | 441 | ||
| 441 | @example | 442 | @example |
| 442 | Emacs.pane.menubar.faceName: none | 443 | Emacs.pane.menubar.faceName: none |
| 444 | Emacs.pane.dialog.faceName: none | ||
| 443 | @end example | 445 | @end example |
| 444 | 446 | ||
| 445 | @noindent | 447 | @noindent |
| @@ -477,7 +479,7 @@ Emacs.menu*.font: 8x16 | |||
| 477 | For dialog boxes, use @samp{dialog*}: | 479 | For dialog boxes, use @samp{dialog*}: |
| 478 | 480 | ||
| 479 | @example | 481 | @example |
| 480 | Emacs.dialog*.font: 8x16 | 482 | Emacs.dialog*.faceName: Sans-12 |
| 481 | @end example | 483 | @end example |
| 482 | 484 | ||
| 483 | @noindent | 485 | @noindent |
| @@ -65,7 +65,8 @@ Algorithm. | |||
| 65 | ** GTK scroll-bars are now placed on the right by default. | 65 | ** GTK scroll-bars are now placed on the right by default. |
| 66 | Use `set-scroll-bar-mode' to change this. | 66 | Use `set-scroll-bar-mode' to change this. |
| 67 | 67 | ||
| 68 | ** Lucid menus can display antialiased fonts if Emacs is build with Xft. | 68 | ** Lucid menus and dialogs can display antialiased fonts if Emacs is built |
| 69 | with Xft. | ||
| 69 | 70 | ||
| 70 | ** New scrolling commands `scroll-up-command' and `scroll-down-command' | 71 | ** New scrolling commands `scroll-up-command' and `scroll-down-command' |
| 71 | (bound to [next] and [prior]) does not signal errors at top/bottom | 72 | (bound to [next] and [prior]) does not signal errors at top/bottom |
diff --git a/lwlib/ChangeLog b/lwlib/ChangeLog index 189e2c65e10..f0f9c34519e 100644 --- a/lwlib/ChangeLog +++ b/lwlib/ChangeLog | |||
| @@ -1,3 +1,23 @@ | |||
| 1 | 2010-04-11 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * lwlib-Xaw.c (widget_xft_data): New for Xft data. | ||
| 4 | (fill_xft_data, openFont, get_text_width_and_height) | ||
| 5 | (draw_text, set_text, find_xft_data, command_press) | ||
| 6 | (command_reset): New functions. | ||
| 7 | (xaw_update_one_widget): Call set_text for dialog and buttons | ||
| 8 | if HAVE_XFT. Also set internalHeight for buttons. | ||
| 9 | (xaw_destroy_instance): Free all Xft related data. | ||
| 10 | (button_actions, buttonTrans): New structures. | ||
| 11 | (make_dialog): Call XtAppAddActions for button_actions. | ||
| 12 | Find xft font to use and call fill_xft_data for widgets. | ||
| 13 | (xaw_create_dialog): Pass instance parameter to make_dialog. | ||
| 14 | |||
| 15 | * lwlib-int.h (_widget_instance): Add Xft data if HAVE_XFT. | ||
| 16 | Override translations for buttons. If depth is 16 or more, tell | ||
| 17 | Xaw3d to not be nice to colormap. | ||
| 18 | Remove separator widget, use XtNhorizDistance on first right button | ||
| 19 | instead. | ||
| 20 | |||
| 1 | 2010-04-08 Jan Djärv <jan.h.d@swipnet.se> | 21 | 2010-04-08 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 22 | ||
| 3 | * xlwmenu.c (xlwmenu_default_font): Make static. | 23 | * xlwmenu.c (xlwmenu_default_font): Make static. |
diff --git a/lwlib/lwlib-Xaw.c b/lwlib/lwlib-Xaw.c index 2af44cd2e1d..c6bbae7e3c9 100644 --- a/lwlib/lwlib-Xaw.c +++ b/lwlib/lwlib-Xaw.c | |||
| @@ -54,6 +54,22 @@ Boston, MA 02110-1301, USA. */ | |||
| 54 | 54 | ||
| 55 | #include <X11/Xatom.h> | 55 | #include <X11/Xatom.h> |
| 56 | 56 | ||
| 57 | #ifdef HAVE_XFT | ||
| 58 | #include <X11/Xft/Xft.h> | ||
| 59 | |||
| 60 | struct widget_xft_data | ||
| 61 | { | ||
| 62 | Widget widget; | ||
| 63 | XftFont *xft_font; | ||
| 64 | XftDraw *xft_draw; | ||
| 65 | XftColor xft_fg, xft_bg; | ||
| 66 | int p_width, p_height; | ||
| 67 | Pixmap p; | ||
| 68 | }; | ||
| 69 | |||
| 70 | |||
| 71 | #endif | ||
| 72 | |||
| 57 | static void xaw_generic_callback (/*Widget, XtPointer, XtPointer*/); | 73 | static void xaw_generic_callback (/*Widget, XtPointer, XtPointer*/); |
| 58 | 74 | ||
| 59 | 75 | ||
| @@ -130,6 +146,207 @@ xaw_update_scrollbar (instance, widget, val) | |||
| 130 | } | 146 | } |
| 131 | #endif | 147 | #endif |
| 132 | 148 | ||
| 149 | #ifdef HAVE_XFT | ||
| 150 | static void | ||
| 151 | fill_xft_data (struct widget_xft_data *data, Widget widget, XftFont *font) | ||
| 152 | { | ||
| 153 | data->widget = widget; | ||
| 154 | data->xft_font = font; | ||
| 155 | Pixel bg, fg; | ||
| 156 | XColor colors[2]; | ||
| 157 | int screen = XScreenNumberOfScreen (XtScreen (widget)); | ||
| 158 | |||
| 159 | XtVaGetValues (widget, | ||
| 160 | XtNbackground, &bg, | ||
| 161 | XtNforeground, &fg, | ||
| 162 | NULL); | ||
| 163 | |||
| 164 | colors[0].pixel = data->xft_fg.pixel = fg; | ||
| 165 | colors[1].pixel = data->xft_bg.pixel = bg; | ||
| 166 | XQueryColors (XtDisplay (widget), | ||
| 167 | DefaultColormapOfScreen (XtScreen (widget)), | ||
| 168 | colors, 2); | ||
| 169 | |||
| 170 | data->xft_fg.color.alpha = 0xFFFF; | ||
| 171 | data->xft_fg.color.red = colors[0].red; | ||
| 172 | data->xft_fg.color.green = colors[0].green; | ||
| 173 | data->xft_fg.color.blue = colors[0].blue; | ||
| 174 | data->xft_bg.color.alpha = 0xFFFF; | ||
| 175 | data->xft_bg.color.red = colors[1].red; | ||
| 176 | data->xft_bg.color.green = colors[1].green; | ||
| 177 | data->xft_bg.color.blue = colors[1].blue; | ||
| 178 | |||
| 179 | data->p = None; | ||
| 180 | data->xft_draw = 0; | ||
| 181 | data->p_width = data->p_height = 0; | ||
| 182 | } | ||
| 183 | |||
| 184 | static XftFont* | ||
| 185 | openFont (Widget widget, char *name) | ||
| 186 | { | ||
| 187 | char *fname = name; | ||
| 188 | int screen = XScreenNumberOfScreen (XtScreen (widget)); | ||
| 189 | int len = strlen (fname), i = len-1; | ||
| 190 | XftFont *fn; | ||
| 191 | |||
| 192 | /* Try to convert Gtk-syntax (Sans 9) to Xft syntax Sans-9. */ | ||
| 193 | while (i > 0 && isdigit (fname[i])) | ||
| 194 | --i; | ||
| 195 | if (fname[i] == ' ') | ||
| 196 | { | ||
| 197 | fname = xstrdup (name); | ||
| 198 | fname[i] = '-'; | ||
| 199 | } | ||
| 200 | |||
| 201 | fn = XftFontOpenName (XtDisplay (widget), screen, fname); | ||
| 202 | if (fname != name) free (fname); | ||
| 203 | |||
| 204 | return fn; | ||
| 205 | } | ||
| 206 | |||
| 207 | static int | ||
| 208 | get_text_width_and_height (Widget widget, char *text, | ||
| 209 | XftFont *xft_font, | ||
| 210 | int *height) | ||
| 211 | { | ||
| 212 | int w = 0, h = 0; | ||
| 213 | char *bp = text; | ||
| 214 | |||
| 215 | while (bp && *bp != '\0') | ||
| 216 | { | ||
| 217 | XGlyphInfo gi; | ||
| 218 | char *cp = strchr (bp, '\n'); | ||
| 219 | XftTextExtentsUtf8 (XtDisplay (widget), xft_font, | ||
| 220 | (FcChar8 *) bp, | ||
| 221 | cp ? cp - bp : strlen (bp), | ||
| 222 | &gi); | ||
| 223 | bp = cp ? cp + 1 : NULL; | ||
| 224 | h += xft_font->height; | ||
| 225 | if (w < gi.width) w = gi.width; | ||
| 226 | } | ||
| 227 | |||
| 228 | *height = h; | ||
| 229 | return w; | ||
| 230 | } | ||
| 231 | |||
| 232 | static void | ||
| 233 | draw_text (struct widget_xft_data *data, char *lbl, int inverse) | ||
| 234 | { | ||
| 235 | Screen *sc = XtScreen (data->widget); | ||
| 236 | int screen = XScreenNumberOfScreen (sc); | ||
| 237 | int y = data->xft_font->ascent; | ||
| 238 | int x = inverse ? 0 : 2; | ||
| 239 | char *bp = lbl; | ||
| 240 | |||
| 241 | data->xft_draw = XftDrawCreate (XtDisplay (data->widget), | ||
| 242 | data->p, | ||
| 243 | DefaultVisual (XtDisplay (data->widget), | ||
| 244 | screen), | ||
| 245 | DefaultColormapOfScreen (sc)); | ||
| 246 | XftDrawRect (data->xft_draw, | ||
| 247 | inverse ? &data->xft_fg : &data->xft_bg, | ||
| 248 | 0, 0, data->p_width, data->p_height); | ||
| 249 | |||
| 250 | if (!inverse) y += 2; | ||
| 251 | while (bp && *bp != '\0') | ||
| 252 | { | ||
| 253 | char *cp = strchr (bp, '\n'); | ||
| 254 | XftDrawStringUtf8 (data->xft_draw, | ||
| 255 | inverse ? &data->xft_bg : &data->xft_fg, | ||
| 256 | data->xft_font, x, y, bp, cp ? cp - bp : strlen (bp)); | ||
| 257 | bp = cp ? cp + 1 : NULL; | ||
| 258 | /* 1.2 gives reasonable line spacing. */ | ||
| 259 | y += data->xft_font->height * 1.2; | ||
| 260 | } | ||
| 261 | |||
| 262 | } | ||
| 263 | |||
| 264 | |||
| 265 | static void | ||
| 266 | set_text (struct widget_xft_data *data, Widget toplevel, char *lbl, int margin) | ||
| 267 | { | ||
| 268 | int screen = XScreenNumberOfScreen (XtScreen (data->widget)); | ||
| 269 | int width, height; | ||
| 270 | |||
| 271 | width = get_text_width_and_height (data->widget, lbl, data->xft_font, | ||
| 272 | &height); | ||
| 273 | data->p_width = width + margin; | ||
| 274 | data->p_height = height + margin; | ||
| 275 | |||
| 276 | data->p = XCreatePixmap (XtDisplay (data->widget), | ||
| 277 | XtWindow (toplevel), | ||
| 278 | data->p_width, | ||
| 279 | data->p_height, | ||
| 280 | DefaultDepthOfScreen (XtScreen (data->widget))); | ||
| 281 | draw_text (data, lbl, 0); | ||
| 282 | XtVaSetValues (data->widget, XtNbitmap, data->p, NULL); | ||
| 283 | } | ||
| 284 | |||
| 285 | static struct widget_xft_data * | ||
| 286 | find_xft_data (Widget widget) | ||
| 287 | { | ||
| 288 | widget_instance *inst = NULL; | ||
| 289 | Widget parent = XtParent (widget); | ||
| 290 | struct widget_xft_data *data = NULL; | ||
| 291 | int nr; | ||
| 292 | while (parent && !inst) | ||
| 293 | { | ||
| 294 | inst = lw_get_widget_instance (parent); | ||
| 295 | parent = XtParent (parent); | ||
| 296 | } | ||
| 297 | if (!inst || !inst->xft_data || !inst->xft_data[0].xft_font) return; | ||
| 298 | |||
| 299 | for (nr = 0; data == NULL && nr < inst->nr_xft_data; ++nr) | ||
| 300 | { | ||
| 301 | if (inst->xft_data[nr].widget == widget) | ||
| 302 | data = &inst->xft_data[nr]; | ||
| 303 | } | ||
| 304 | |||
| 305 | return data; | ||
| 306 | } | ||
| 307 | |||
| 308 | static void | ||
| 309 | command_press (Widget widget, | ||
| 310 | XEvent* event, | ||
| 311 | String *params, | ||
| 312 | Cardinal *num_params) | ||
| 313 | { | ||
| 314 | struct widget_xft_data *data = find_xft_data (widget); | ||
| 315 | if (data) | ||
| 316 | { | ||
| 317 | char *lbl; | ||
| 318 | /* Since this isn't used for rectangle buttons, use it to for armed. */ | ||
| 319 | XtVaSetValues (widget, XtNcornerRoundPercent, 1, NULL); | ||
| 320 | |||
| 321 | XtVaGetValues (widget, XtNlabel, &lbl, NULL); | ||
| 322 | draw_text (data, lbl, 1); | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | static void | ||
| 327 | command_reset (Widget widget, | ||
| 328 | XEvent* event, | ||
| 329 | String *params, | ||
| 330 | Cardinal *num_params) | ||
| 331 | { | ||
| 332 | struct widget_xft_data *data = find_xft_data (widget); | ||
| 333 | if (data) | ||
| 334 | { | ||
| 335 | Dimension cr; | ||
| 336 | XtVaGetValues (widget, XtNcornerRoundPercent, &cr, NULL); | ||
| 337 | if (cr == 1) | ||
| 338 | { | ||
| 339 | char *lbl; | ||
| 340 | XtVaSetValues (widget, XtNcornerRoundPercent, 0, NULL); | ||
| 341 | XtVaGetValues (widget, XtNlabel, &lbl, NULL); | ||
| 342 | draw_text (data, lbl, 0); | ||
| 343 | } | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 | |||
| 348 | #endif | ||
| 349 | |||
| 133 | void | 350 | void |
| 134 | #ifdef PROTOTYPES | 351 | #ifdef PROTOTYPES |
| 135 | xaw_update_one_widget (widget_instance *instance, Widget widget, | 352 | xaw_update_one_widget (widget_instance *instance, Widget widget, |
| @@ -150,15 +367,21 @@ xaw_update_one_widget (instance, widget, val, deep_p) | |||
| 150 | #endif | 367 | #endif |
| 151 | if (XtIsSubclass (widget, dialogWidgetClass)) | 368 | if (XtIsSubclass (widget, dialogWidgetClass)) |
| 152 | { | 369 | { |
| 153 | Arg al[1]; | 370 | |
| 154 | int ac = 0; | 371 | #ifdef HAVE_XFT |
| 155 | XtSetArg (al[ac], XtNlabel, val->contents->value); ac++; | 372 | if (instance->xft_data && instance->xft_data[0].xft_font) |
| 156 | XtSetValues (widget, al, ac); | 373 | { |
| 374 | set_text (&instance->xft_data[0], instance->parent, | ||
| 375 | val->contents->value, 10); | ||
| 376 | } | ||
| 377 | #endif | ||
| 378 | XtVaSetValues (widget, XtNlabel, val->contents->value, NULL); | ||
| 157 | } | 379 | } |
| 158 | else if (XtIsSubclass (widget, commandWidgetClass)) | 380 | else if (XtIsSubclass (widget, commandWidgetClass)) |
| 159 | { | 381 | { |
| 160 | Dimension bw = 0; | 382 | Dimension bw = 0; |
| 161 | Arg al[3]; | 383 | Arg al[10]; |
| 384 | int ac = 0; | ||
| 162 | 385 | ||
| 163 | XtVaGetValues (widget, XtNborderWidth, &bw, NULL); | 386 | XtVaGetValues (widget, XtNborderWidth, &bw, NULL); |
| 164 | if (bw == 0) | 387 | if (bw == 0) |
| @@ -174,10 +397,30 @@ xaw_update_one_widget (instance, widget, val, deep_p) | |||
| 174 | } | 397 | } |
| 175 | 398 | ||
| 176 | XtSetSensitive (widget, val->enabled); | 399 | XtSetSensitive (widget, val->enabled); |
| 177 | XtSetArg (al[0], XtNlabel, val->value); | 400 | XtSetArg (al[ac], XtNlabel, val->value);ac++; |
| 178 | /* Force centered button text. Se above. */ | 401 | /* Force centered button text. Se above. */ |
| 179 | XtSetArg (al[1], XtNjustify, XtJustifyCenter); | 402 | XtSetArg (al[ac], XtNjustify, XtJustifyCenter);ac++; |
| 180 | XtSetValues (widget, al, 2); | 403 | #ifdef HAVE_XFT |
| 404 | if (instance->xft_data && instance->xft_data[0].xft_font) | ||
| 405 | { | ||
| 406 | int th; | ||
| 407 | int nr; | ||
| 408 | for (nr = 0; nr < instance->nr_xft_data; ++nr) | ||
| 409 | if (instance->xft_data[nr].widget == widget) | ||
| 410 | break; | ||
| 411 | if (nr < instance->nr_xft_data) | ||
| 412 | { | ||
| 413 | set_text (&instance->xft_data[nr], instance->parent, | ||
| 414 | val->value, 6); | ||
| 415 | |||
| 416 | /* Must set internalHeight to twice the highlight thickness, | ||
| 417 | or else it gets overwritten by our pixmap. Probably a bug. */ | ||
| 418 | XtVaGetValues (widget, XtNhighlightThickness, &th, NULL); | ||
| 419 | XtSetArg (al[ac], XtNinternalHeight, 2*th);ac++; | ||
| 420 | } | ||
| 421 | } | ||
| 422 | #endif | ||
| 423 | XtSetValues (widget, al, ac); | ||
| 181 | XtRemoveAllCallbacks (widget, XtNcallback); | 424 | XtRemoveAllCallbacks (widget, XtNcallback); |
| 182 | XtAddCallback (widget, XtNcallback, xaw_generic_callback, instance); | 425 | XtAddCallback (widget, XtNcallback, xaw_generic_callback, instance); |
| 183 | } | 426 | } |
| @@ -198,6 +441,28 @@ void | |||
| 198 | xaw_destroy_instance (instance) | 441 | xaw_destroy_instance (instance) |
| 199 | widget_instance *instance; | 442 | widget_instance *instance; |
| 200 | { | 443 | { |
| 444 | #ifdef HAVE_XFT | ||
| 445 | if (instance->xft_data) | ||
| 446 | { | ||
| 447 | int i; | ||
| 448 | for (i = 0; i < instance->nr_xft_data; ++i) | ||
| 449 | { | ||
| 450 | if (instance->xft_data[i].xft_draw) | ||
| 451 | XftDrawDestroy (instance->xft_data[i].xft_draw); | ||
| 452 | if (instance->xft_data[i].p != None) | ||
| 453 | { | ||
| 454 | XtVaSetValues (instance->xft_data[i].widget, XtNbitmap, None, | ||
| 455 | NULL); | ||
| 456 | XFreePixmap (XtDisplay (instance->widget), | ||
| 457 | instance->xft_data[i].p); | ||
| 458 | } | ||
| 459 | } | ||
| 460 | if (instance->xft_data[0].xft_font) | ||
| 461 | XftFontClose (XtDisplay (instance->widget), | ||
| 462 | instance->xft_data[0].xft_font); | ||
| 463 | free (instance->xft_data); | ||
| 464 | } | ||
| 465 | #endif | ||
| 201 | if (XtIsSubclass (instance->widget, dialogWidgetClass)) | 466 | if (XtIsSubclass (instance->widget, dialogWidgetClass)) |
| 202 | /* Need to destroy the Shell too. */ | 467 | /* Need to destroy the Shell too. */ |
| 203 | XtDestroyWidget (XtParent (instance->widget)); | 468 | XtDestroyWidget (XtParent (instance->widget)); |
| @@ -298,8 +563,21 @@ static XtActionsRec xaw_actions [] = { | |||
| 298 | }; | 563 | }; |
| 299 | static Boolean actions_initted = False; | 564 | static Boolean actions_initted = False; |
| 300 | 565 | ||
| 566 | #ifdef HAVE_XFT | ||
| 567 | static XtActionsRec button_actions[] = | ||
| 568 | { | ||
| 569 | { "my_reset", command_reset }, | ||
| 570 | { "my_press", command_press }, | ||
| 571 | }; | ||
| 572 | char buttonTrans[] = | ||
| 573 | "<Leave>: reset() my_reset()\n" | ||
| 574 | "<Btn1Down>: set() my_press()\n" | ||
| 575 | "<Btn1Up>: my_reset() notify() unset()\n"; | ||
| 576 | #endif | ||
| 577 | |||
| 301 | static Widget | 578 | static Widget |
| 302 | make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, radio_box, list, left_buttons, right_buttons) | 579 | make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, |
| 580 | radio_box, list, left_buttons, right_buttons, instance) | ||
| 303 | char* name; | 581 | char* name; |
| 304 | Widget parent; | 582 | Widget parent; |
| 305 | Boolean pop_up_p; | 583 | Boolean pop_up_p; |
| @@ -310,6 +588,7 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, ra | |||
| 310 | Boolean list; | 588 | Boolean list; |
| 311 | int left_buttons; | 589 | int left_buttons; |
| 312 | int right_buttons; | 590 | int right_buttons; |
| 591 | widget_instance *instance; | ||
| 313 | { | 592 | { |
| 314 | Arg av [20]; | 593 | Arg av [20]; |
| 315 | int ac = 0; | 594 | int ac = 0; |
| @@ -319,6 +598,10 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, ra | |||
| 319 | Widget dialog; | 598 | Widget dialog; |
| 320 | Widget button; | 599 | Widget button; |
| 321 | XtTranslations override; | 600 | XtTranslations override; |
| 601 | #ifdef HAVE_XFT | ||
| 602 | XftFont *xft_font = 0; | ||
| 603 | XtTranslations button_override; | ||
| 604 | #endif | ||
| 322 | 605 | ||
| 323 | if (! pop_up_p) abort (); /* not implemented */ | 606 | if (! pop_up_p) abort (); /* not implemented */ |
| 324 | if (text_input_slot) abort (); /* not implemented */ | 607 | if (text_input_slot) abort (); /* not implemented */ |
| @@ -330,6 +613,10 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, ra | |||
| 330 | XtAppContext app = XtWidgetToApplicationContext (parent); | 613 | XtAppContext app = XtWidgetToApplicationContext (parent); |
| 331 | XtAppAddActions (app, xaw_actions, | 614 | XtAppAddActions (app, xaw_actions, |
| 332 | sizeof (xaw_actions) / sizeof (xaw_actions[0])); | 615 | sizeof (xaw_actions) / sizeof (xaw_actions[0])); |
| 616 | #ifdef HAVE_XFT | ||
| 617 | XtAppAddActions (app, button_actions, | ||
| 618 | sizeof (button_actions) / sizeof (button_actions[0])); | ||
| 619 | #endif | ||
| 333 | actions_initted = True; | 620 | actions_initted = True; |
| 334 | } | 621 | } |
| 335 | 622 | ||
| @@ -351,6 +638,49 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, ra | |||
| 351 | override = XtParseTranslationTable (dialogOverride); | 638 | override = XtParseTranslationTable (dialogOverride); |
| 352 | XtOverrideTranslations (dialog, override); | 639 | XtOverrideTranslations (dialog, override); |
| 353 | 640 | ||
| 641 | #ifdef HAVE_XFT | ||
| 642 | { | ||
| 643 | int num; | ||
| 644 | Widget *ch = NULL; | ||
| 645 | Widget w = 0; | ||
| 646 | XtVaGetValues (dialog, | ||
| 647 | XtNnumChildren, &num, | ||
| 648 | XtNchildren, &ch, NULL); | ||
| 649 | for (i = 0; i < num; ++i) | ||
| 650 | { | ||
| 651 | if (!XtIsSubclass (ch[i], commandWidgetClass) | ||
| 652 | && XtIsSubclass (ch[i], labelWidgetClass)) | ||
| 653 | { | ||
| 654 | w = ch[i]; | ||
| 655 | break; | ||
| 656 | } | ||
| 657 | } | ||
| 658 | instance->xft_data = 0; | ||
| 659 | instance->nr_xft_data = 0; | ||
| 660 | if (w) | ||
| 661 | { | ||
| 662 | XtResource rec[] = | ||
| 663 | { { "faceName", "FaceName", XtRString, sizeof(String), 0, XtRString, | ||
| 664 | (XtPointer)"Sans-14" }}; | ||
| 665 | char *faceName; | ||
| 666 | XtVaGetSubresources (dialog, &faceName, "Dialog", "dialog", | ||
| 667 | rec, 1, 0, NULL); | ||
| 668 | if (strcmp ("none", faceName) != 0) | ||
| 669 | xft_font = openFont (dialog, faceName); | ||
| 670 | if (xft_font) | ||
| 671 | { | ||
| 672 | instance->nr_xft_data = left_buttons + right_buttons + 1; | ||
| 673 | instance->xft_data = calloc (instance->nr_xft_data, | ||
| 674 | sizeof(*instance->xft_data)); | ||
| 675 | |||
| 676 | fill_xft_data (&instance->xft_data[0], w, xft_font); | ||
| 677 | } | ||
| 678 | } | ||
| 679 | |||
| 680 | button_override = XtParseTranslationTable (buttonTrans); | ||
| 681 | } | ||
| 682 | #endif | ||
| 683 | |||
| 354 | bc = 0; | 684 | bc = 0; |
| 355 | button = 0; | 685 | button = 0; |
| 356 | for (i = 0; i < left_buttons; i++) | 686 | for (i = 0; i < left_buttons; i++) |
| @@ -362,51 +692,56 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, ra | |||
| 362 | XtSetArg (av [ac], XtNtop, XtChainBottom); ac++; | 692 | XtSetArg (av [ac], XtNtop, XtChainBottom); ac++; |
| 363 | XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++; | 693 | XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++; |
| 364 | XtSetArg (av [ac], XtNresizable, True); ac++; | 694 | XtSetArg (av [ac], XtNresizable, True); ac++; |
| 695 | #ifdef HAVE_XAW3D | ||
| 696 | if (DefaultDepthOfScreen (XtScreen (dialog)) >= 16) | ||
| 697 | { | ||
| 698 | /* Turn of dithered shadow if we can. Looks bad */ | ||
| 699 | XtSetArg (av [ac], "beNiceToColormap", False); ac++; | ||
| 700 | } | ||
| 701 | #endif | ||
| 365 | sprintf (button_name, "button%d", ++bc); | 702 | sprintf (button_name, "button%d", ++bc); |
| 366 | button = XtCreateManagedWidget (button_name, commandWidgetClass, | 703 | button = XtCreateManagedWidget (button_name, commandWidgetClass, |
| 367 | dialog, av, ac); | 704 | dialog, av, ac); |
| 705 | #ifdef HAVE_XFT | ||
| 706 | if (xft_font) | ||
| 707 | { | ||
| 708 | fill_xft_data (&instance->xft_data[bc], button, xft_font); | ||
| 709 | XtOverrideTranslations (button, button_override); | ||
| 710 | } | ||
| 711 | #endif | ||
| 368 | } | 712 | } |
| 369 | if (right_buttons) | ||
| 370 | { | ||
| 371 | /* Create a separator | ||
| 372 | 713 | ||
| 373 | I want the separator to take up the slack between the buttons on | ||
| 374 | the right and the buttons on the left (that is I want the buttons | ||
| 375 | after the separator to be packed against the right edge of the | ||
| 376 | window) but I can't seem to make it do it. | ||
| 377 | */ | ||
| 378 | ac = 0; | ||
| 379 | XtSetArg (av [ac], XtNfromHoriz, button); ac++; | ||
| 380 | /* XtSetArg (av [ac], XtNfromVert, XtNameToWidget (dialog, "label")); ac++; */ | ||
| 381 | XtSetArg (av [ac], XtNleft, XtChainLeft); ac++; | ||
| 382 | XtSetArg (av [ac], XtNright, XtChainRight); ac++; | ||
| 383 | XtSetArg (av [ac], XtNtop, XtChainBottom); ac++; | ||
| 384 | XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++; | ||
| 385 | XtSetArg (av [ac], XtNlabel, ""); ac++; | ||
| 386 | XtSetArg (av [ac], XtNwidth, 30); ac++; /* #### aaack!! */ | ||
| 387 | XtSetArg (av [ac], XtNborderWidth, 0); ac++; | ||
| 388 | XtSetArg (av [ac], XtNshapeStyle, XmuShapeRectangle); ac++; | ||
| 389 | XtSetArg (av [ac], XtNresizable, False); ac++; | ||
| 390 | XtSetArg (av [ac], XtNsensitive, False); ac++; | ||
| 391 | button = XtCreateManagedWidget ("separator", | ||
| 392 | /* labelWidgetClass, */ | ||
| 393 | /* This has to be Command to fake out | ||
| 394 | the Dialog widget... */ | ||
| 395 | commandWidgetClass, | ||
| 396 | dialog, av, ac); | ||
| 397 | } | ||
| 398 | for (i = 0; i < right_buttons; i++) | 714 | for (i = 0; i < right_buttons; i++) |
| 399 | { | 715 | { |
| 400 | ac = 0; | 716 | ac = 0; |
| 401 | XtSetArg (av [ac], XtNfromHoriz, button); ac++; | 717 | XtSetArg (av [ac], XtNfromHoriz, button); ac++; |
| 718 | if (i == 0) | ||
| 719 | { | ||
| 720 | /* Separator to the other buttons. */ | ||
| 721 | XtSetArg (av [ac], XtNhorizDistance, 30); ac++; | ||
| 722 | } | ||
| 402 | XtSetArg (av [ac], XtNleft, XtChainRight); ac++; | 723 | XtSetArg (av [ac], XtNleft, XtChainRight); ac++; |
| 403 | XtSetArg (av [ac], XtNright, XtChainRight); ac++; | 724 | XtSetArg (av [ac], XtNright, XtChainRight); ac++; |
| 404 | XtSetArg (av [ac], XtNtop, XtChainBottom); ac++; | 725 | XtSetArg (av [ac], XtNtop, XtChainBottom); ac++; |
| 405 | XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++; | 726 | XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++; |
| 406 | XtSetArg (av [ac], XtNresizable, True); ac++; | 727 | XtSetArg (av [ac], XtNresizable, True); ac++; |
| 728 | #ifdef HAVE_XAW3D | ||
| 729 | if (DefaultDepthOfScreen (XtScreen (dialog)) >= 16) | ||
| 730 | { | ||
| 731 | /* Turn of dithered shadow if we can. Looks bad */ | ||
| 732 | XtSetArg (av [ac], "beNiceToColormap", False); ac++; | ||
| 733 | } | ||
| 734 | #endif | ||
| 407 | sprintf (button_name, "button%d", ++bc); | 735 | sprintf (button_name, "button%d", ++bc); |
| 408 | button = XtCreateManagedWidget (button_name, commandWidgetClass, | 736 | button = XtCreateManagedWidget (button_name, commandWidgetClass, |
| 409 | dialog, av, ac); | 737 | dialog, av, ac); |
| 738 | #ifdef HAVE_XFT | ||
| 739 | if (xft_font) | ||
| 740 | { | ||
| 741 | fill_xft_data (&instance->xft_data[bc], button, xft_font); | ||
| 742 | XtOverrideTranslations (button, button_override); | ||
| 743 | } | ||
| 744 | #endif | ||
| 410 | } | 745 | } |
| 411 | 746 | ||
| 412 | return dialog; | 747 | return dialog; |
| @@ -472,8 +807,7 @@ xaw_create_dialog (instance) | |||
| 472 | 807 | ||
| 473 | widget = make_dialog (name, parent, pop_up_p, | 808 | widget = make_dialog (name, parent, pop_up_p, |
| 474 | shell_name, icon_name, text_input_slot, radio_box, | 809 | shell_name, icon_name, text_input_slot, radio_box, |
| 475 | list, left_buttons, right_buttons); | 810 | list, left_buttons, right_buttons, instance); |
| 476 | |||
| 477 | return widget; | 811 | return widget; |
| 478 | } | 812 | } |
| 479 | 813 | ||
diff --git a/lwlib/lwlib-int.h b/lwlib/lwlib-int.h index 6bcf558dc51..ba48d191752 100644 --- a/lwlib/lwlib-int.h +++ b/lwlib/lwlib-int.h | |||
| @@ -28,11 +28,17 @@ Boston, MA 02110-1301, USA. */ | |||
| 28 | 28 | ||
| 29 | extern char *safe_strdup __P ((const char *)); | 29 | extern char *safe_strdup __P ((const char *)); |
| 30 | 30 | ||
| 31 | struct widget_xft_data; | ||
| 32 | |||
| 31 | typedef struct _widget_instance | 33 | typedef struct _widget_instance |
| 32 | { | 34 | { |
| 33 | Widget widget; | 35 | Widget widget; |
| 34 | Widget parent; | 36 | Widget parent; |
| 35 | Boolean pop_up_p; | 37 | Boolean pop_up_p; |
| 38 | #ifdef HAVE_XFT | ||
| 39 | struct widget_xft_data *xft_data; | ||
| 40 | int nr_xft_data; | ||
| 41 | #endif | ||
| 36 | struct _widget_info* info; | 42 | struct _widget_info* info; |
| 37 | struct _widget_instance* next; | 43 | struct _widget_instance* next; |
| 38 | } widget_instance; | 44 | } widget_instance; |
diff --git a/src/ChangeLog b/src/ChangeLog index 92a05505d91..476f68e142b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2010-04-11 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * xmenu.c (apply_systemfont_to_dialog): New. | ||
| 4 | (create_and_show_dialog): Call apply_systemfont_to_dialog if HAVE_XFT. | ||
| 5 | |||
| 1 | 2010-04-11 Stefan Monnier <monnier@iro.umontreal.ca> | 6 | 2010-04-11 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 7 | ||
| 3 | * process.c (exec_sentinel): Preserve current-buffer. | 8 | * process.c (exec_sentinel): Preserve current-buffer. |
diff --git a/src/xmenu.c b/src/xmenu.c index de2f4eb6815..c8067a47deb 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -954,6 +954,19 @@ update_frame_menubar (f) | |||
| 954 | 954 | ||
| 955 | #ifdef USE_LUCID | 955 | #ifdef USE_LUCID |
| 956 | static void | 956 | static void |
| 957 | apply_systemfont_to_dialog (w) | ||
| 958 | Widget w; | ||
| 959 | { | ||
| 960 | const char *fn = xsettings_get_system_normal_font (); | ||
| 961 | if (fn) | ||
| 962 | { | ||
| 963 | XrmDatabase db = XtDatabase (XtDisplay (w)); | ||
| 964 | if (db) | ||
| 965 | XrmPutStringResource (&db, "*dialog.faceName", fn); | ||
| 966 | } | ||
| 967 | } | ||
| 968 | |||
| 969 | static void | ||
| 957 | apply_systemfont_to_menu (w) | 970 | apply_systemfont_to_menu (w) |
| 958 | Widget w; | 971 | Widget w; |
| 959 | { | 972 | { |
| @@ -964,15 +977,15 @@ apply_systemfont_to_menu (w) | |||
| 964 | 977 | ||
| 965 | if (XtIsShell (w)) /* popup menu */ | 978 | if (XtIsShell (w)) /* popup menu */ |
| 966 | { | 979 | { |
| 967 | Widget *childs[1]; | 980 | Widget *childs = NULL; |
| 968 | int num = 0; | 981 | int num = 0; |
| 969 | 982 | ||
| 970 | XtVaGetValues (w, XtNnumChildren, &num, NULL); | 983 | XtVaGetValues (w, XtNnumChildren, &num, NULL); |
| 971 | if (num != 1) return; /* Should only be one. */ | 984 | if (num != 1) return; /* Should only be one. */ |
| 972 | 985 | ||
| 973 | childs[0] = 0; | 986 | childs[0] = 0; |
| 974 | XtVaGetValues (w, XtNchildren, childs, NULL); | 987 | XtVaGetValues (w, XtNchildren, &childs, NULL); |
| 975 | if (childs[0] && *childs[0]) w = *childs[0]; | 988 | if (childs && *childs) w = *childs; |
| 976 | } | 989 | } |
| 977 | 990 | ||
| 978 | /* Only use system font if the default is used for the menu. */ | 991 | /* Only use system font if the default is used for the menu. */ |
| @@ -2047,11 +2060,13 @@ create_and_show_dialog (f, first_wv) | |||
| 2047 | abort(); | 2060 | abort(); |
| 2048 | 2061 | ||
| 2049 | dialog_id = widget_id_tick++; | 2062 | dialog_id = widget_id_tick++; |
| 2063 | #ifdef HAVE_XFT | ||
| 2064 | apply_systemfont_to_dialog (f->output_data.x->widget); | ||
| 2065 | #endif | ||
| 2050 | lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv, | 2066 | lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv, |
| 2051 | f->output_data.x->widget, 1, 0, | 2067 | f->output_data.x->widget, 1, 0, |
| 2052 | dialog_selection_callback, 0, 0); | 2068 | dialog_selection_callback, 0, 0); |
| 2053 | lw_modify_all_widgets (dialog_id, first_wv->contents, True); | 2069 | lw_modify_all_widgets (dialog_id, first_wv->contents, True); |
| 2054 | |||
| 2055 | /* Display the dialog box. */ | 2070 | /* Display the dialog box. */ |
| 2056 | lw_pop_up_all_widgets (dialog_id); | 2071 | lw_pop_up_all_widgets (dialog_id); |
| 2057 | popup_activated_flag = 1; | 2072 | popup_activated_flag = 1; |