diff options
| author | Eli Zaretskii | 2013-09-29 21:38:56 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-09-29 21:38:56 +0300 |
| commit | 0afa0aabd833fff2e8da06e24da6c4bab7aadec3 (patch) | |
| tree | 9420b06009efbb982e29d0fc2da77079d1cc5fd4 /src/menu.c | |
| parent | 0fe3602a281b967ab1709da511c88f763a86e62a (diff) | |
| download | emacs-0afa0aabd833fff2e8da06e24da6c4bab7aadec3.tar.gz emacs-0afa0aabd833fff2e8da06e24da6c4bab7aadec3.zip | |
x-popup-dialog fixed, almost.
Diffstat (limited to 'src/menu.c')
| -rw-r--r-- | src/menu.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/menu.c b/src/menu.c index 5ca687f3d8a..7c34a9cacd4 100644 --- a/src/menu.c +++ b/src/menu.c | |||
| @@ -1376,6 +1376,141 @@ no quit occurs and `x-popup-menu' returns nil. */) | |||
| 1376 | return selection; | 1376 | return selection; |
| 1377 | } | 1377 | } |
| 1378 | 1378 | ||
| 1379 | #ifdef HAVE_MENUS | ||
| 1380 | |||
| 1381 | DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0, | ||
| 1382 | doc: /* Pop up a dialog box and return user's selection. | ||
| 1383 | POSITION specifies which frame to use. | ||
| 1384 | This is normally a mouse button event or a window or frame. | ||
| 1385 | If POSITION is t, it means to use the frame the mouse is on. | ||
| 1386 | The dialog box appears in the middle of the specified frame. | ||
| 1387 | |||
| 1388 | CONTENTS specifies the alternatives to display in the dialog box. | ||
| 1389 | It is a list of the form (DIALOG ITEM1 ITEM2...). | ||
| 1390 | Each ITEM is a cons cell (STRING . VALUE). | ||
| 1391 | The return value is VALUE from the chosen item. | ||
| 1392 | |||
| 1393 | An ITEM may also be just a string--that makes a nonselectable item. | ||
| 1394 | An ITEM may also be nil--that means to put all preceding items | ||
| 1395 | on the left of the dialog box and all following items on the right. | ||
| 1396 | \(By default, approximately half appear on each side.) | ||
| 1397 | |||
| 1398 | If HEADER is non-nil, the frame title for the box is "Information", | ||
| 1399 | otherwise it is "Question". | ||
| 1400 | |||
| 1401 | If the user gets rid of the dialog box without making a valid choice, | ||
| 1402 | for instance using the window manager, then this produces a quit and | ||
| 1403 | `x-popup-dialog' does not return. */) | ||
| 1404 | (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | ||
| 1405 | { | ||
| 1406 | struct frame *f = NULL; | ||
| 1407 | Lisp_Object window; | ||
| 1408 | |||
| 1409 | /* Decode the first argument: find the window or frame to use. */ | ||
| 1410 | if (EQ (position, Qt) | ||
| 1411 | || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) | ||
| 1412 | || EQ (XCAR (position), Qtool_bar)))) | ||
| 1413 | { | ||
| 1414 | #if 0 /* Using the frame the mouse is on may not be right. */ | ||
| 1415 | /* Use the mouse's current position. */ | ||
| 1416 | struct frame *new_f = SELECTED_FRAME (); | ||
| 1417 | Lisp_Object bar_window; | ||
| 1418 | enum scroll_bar_part part; | ||
| 1419 | Time time; | ||
| 1420 | Lisp_Object x, y; | ||
| 1421 | |||
| 1422 | (*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y, &time); | ||
| 1423 | |||
| 1424 | if (new_f != 0) | ||
| 1425 | XSETFRAME (window, new_f); | ||
| 1426 | else | ||
| 1427 | window = selected_window; | ||
| 1428 | #endif | ||
| 1429 | window = selected_window; | ||
| 1430 | } | ||
| 1431 | else if (CONSP (position)) | ||
| 1432 | { | ||
| 1433 | Lisp_Object tem = XCAR (position); | ||
| 1434 | if (CONSP (tem)) | ||
| 1435 | window = Fcar (XCDR (position)); | ||
| 1436 | else | ||
| 1437 | { | ||
| 1438 | tem = Fcar (XCDR (position)); /* EVENT_START (position) */ | ||
| 1439 | window = Fcar (tem); /* POSN_WINDOW (tem) */ | ||
| 1440 | } | ||
| 1441 | } | ||
| 1442 | else if (WINDOWP (position) || FRAMEP (position)) | ||
| 1443 | window = position; | ||
| 1444 | else | ||
| 1445 | window = Qnil; | ||
| 1446 | |||
| 1447 | /* Decode where to put the menu. */ | ||
| 1448 | |||
| 1449 | if (FRAMEP (window)) | ||
| 1450 | f = XFRAME (window); | ||
| 1451 | else if (WINDOWP (window)) | ||
| 1452 | { | ||
| 1453 | CHECK_LIVE_WINDOW (window); | ||
| 1454 | f = XFRAME (WINDOW_FRAME (XWINDOW (window))); | ||
| 1455 | } | ||
| 1456 | else | ||
| 1457 | /* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME, | ||
| 1458 | but I don't want to make one now. */ | ||
| 1459 | CHECK_WINDOW (window); | ||
| 1460 | |||
| 1461 | /* Force a redisplay before showing the dialog. If a frame is created | ||
| 1462 | just before showing the dialog, its contents may not have been fully | ||
| 1463 | drawn, as this depends on timing of events from the X server. Redisplay | ||
| 1464 | is not done when a dialog is shown. If redisplay could be done in the | ||
| 1465 | X event loop (i.e. the X event loop does not run in a signal handler) | ||
| 1466 | this would not be needed. | ||
| 1467 | |||
| 1468 | Do this before creating the widget value that points to Lisp | ||
| 1469 | string contents, because Fredisplay may GC and relocate them. */ | ||
| 1470 | Fredisplay (Qt); | ||
| 1471 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) | ||
| 1472 | if (FRAME_WINDOW_P (f)) | ||
| 1473 | return xw_popup_dialog (f, header, contents); | ||
| 1474 | else | ||
| 1475 | #endif | ||
| 1476 | #if defined (HAVE_NTGUI) && defined (HAVE_DIALOGS) | ||
| 1477 | if (FRAME_W32_P (f)) | ||
| 1478 | return w32_popup_dialog (f, header, contents); | ||
| 1479 | else | ||
| 1480 | #endif | ||
| 1481 | #ifdef HAVE_NS | ||
| 1482 | if (FRAME_NS_P (f)) | ||
| 1483 | return ns_popup_dialog (position, header, contents); | ||
| 1484 | else | ||
| 1485 | #endif | ||
| 1486 | /* Display a menu with these alternatives | ||
| 1487 | in the middle of frame F. */ | ||
| 1488 | { | ||
| 1489 | Lisp_Object x, y, frame, newpos; | ||
| 1490 | int frame_width, frame_height; | ||
| 1491 | |||
| 1492 | if (FRAME_WINDOW_P (f)) | ||
| 1493 | { | ||
| 1494 | frame_width = FRAME_PIXEL_WIDTH (f); | ||
| 1495 | frame_height = FRAME_PIXEL_HEIGHT (f); | ||
| 1496 | } | ||
| 1497 | else | ||
| 1498 | { | ||
| 1499 | frame_width = FRAME_COLS (f); | ||
| 1500 | frame_height = FRAME_LINES (f); | ||
| 1501 | } | ||
| 1502 | XSETFRAME (frame, f); | ||
| 1503 | XSETINT (x, frame_width / 2); | ||
| 1504 | XSETINT (y, frame_height / 2); | ||
| 1505 | newpos = list2 (list2 (x, y), frame); | ||
| 1506 | |||
| 1507 | return Fx_popup_menu (newpos, | ||
| 1508 | list2 (Fcar (contents), contents)); | ||
| 1509 | } | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | #endif /* HAVE_MENUS */ | ||
| 1513 | |||
| 1379 | void | 1514 | void |
| 1380 | syms_of_menu (void) | 1515 | syms_of_menu (void) |
| 1381 | { | 1516 | { |
| @@ -1384,4 +1519,8 @@ syms_of_menu (void) | |||
| 1384 | menu_items_inuse = Qnil; | 1519 | menu_items_inuse = Qnil; |
| 1385 | 1520 | ||
| 1386 | defsubr (&Sx_popup_menu); | 1521 | defsubr (&Sx_popup_menu); |
| 1522 | |||
| 1523 | #ifdef HAVE_MENUS | ||
| 1524 | defsubr (&Sx_popup_dialog); | ||
| 1525 | #endif | ||
| 1387 | } | 1526 | } |