/[emacs]/emacs/src/w32menu.c
ViewVC logotype

Diff of /emacs/src/w32menu.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.68 by jasonr, Tue May 18 19:53:08 2004 UTC revision 1.69 by jasonr, Thu Sep 2 23:22:58 2004 UTC
# Line 45  Boston, MA 02111-1307, USA.  */ Line 45  Boston, MA 02111-1307, USA.  */
45    
46  #include "dispextern.h"  #include "dispextern.h"
47    
 #undef HAVE_MULTILINGUAL_MENU  
48  #undef HAVE_DIALOGS /* TODO: Implement native dialogs.  */  #undef HAVE_DIALOGS /* TODO: Implement native dialogs.  */
49    
50  /******************************************************************/  /******************************************************************/
# Line 66  enum button_type Line 65  enum button_type
65  typedef struct _widget_value  typedef struct _widget_value
66  {  {
67    /* name of widget */    /* name of widget */
68      Lisp_Object   lname;
69    char*         name;    char*         name;
70    /* value (meaning depend on widget type) */    /* value (meaning depend on widget type) */
71    char*         value;    char*         value;
72    /* keyboard equivalent. no implications for XtTranslations */    /* keyboard equivalent. no implications for XtTranslations */
73      Lisp_Object   lkey;
74    char*         key;    char*         key;
75    /* Help string or nil if none.    /* Help string or nil if none.
76       GC finds this string through the frame's menu_bar_vector       GC finds this string through the frame's menu_bar_vector
# Line 136  typedef BOOL (WINAPI * GetMenuItemInfoA_ Line 137  typedef BOOL (WINAPI * GetMenuItemInfoA_
137      IN HMENU,      IN HMENU,
138      IN UINT,      IN UINT,
139      IN BOOL,      IN BOOL,
140      IN OUT LPMENUITEMINFOA      IN OUT LPMENUITEMINFOA);
     );  
141  typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (  typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (
142      IN HMENU,      IN HMENU,
143      IN UINT,      IN UINT,
144      IN BOOL,      IN BOOL,
145      IN LPCMENUITEMINFOA      IN LPCMENUITEMINFOA);
146      );  typedef BOOL (WINAPI * AppendMenuW_Proc) (
147        IN HMENU,
148        IN UINT,
149        IN UINT_PTR,
150        IN LPCWSTR);
151    
152  GetMenuItemInfoA_Proc get_menu_item_info=NULL;  GetMenuItemInfoA_Proc get_menu_item_info = NULL;
153  SetMenuItemInfoA_Proc set_menu_item_info=NULL;  SetMenuItemInfoA_Proc set_menu_item_info = NULL;
154    AppendMenuW_Proc unicode_append_menu = NULL;
155    
156  Lisp_Object Vmenu_updating_frame;  Lisp_Object Vmenu_updating_frame;
157    
# Line 1235  digest_single_submenu (start, end, top_l Line 1240  digest_single_submenu (start, end, top_l
1240            pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);            pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
1241            prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);            prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
1242    
1243  #ifndef HAVE_MULTILINGUAL_MENU            if (STRINGP (pane_name))
           if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))  
1244              {              {
1245                pane_name = ENCODE_SYSTEM (pane_name);                if (unicode_append_menu)
1246                    /* Encode as UTF-8 for now.  */
1247                    pane_name = ENCODE_UTF_8 (pane_name);
1248                  else if (STRING_MULTIBYTE (pane_name))
1249                    pane_name = ENCODE_SYSTEM (pane_name);
1250    
1251                ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);                ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
1252              }              }
1253  #endif  
1254            pane_string = (NILP (pane_name)            pane_string = (NILP (pane_name)
1255                           ? "" : (char *) SDATA (pane_name));                           ? "" : (char *) SDATA (pane_name));
1256            /* If there is just one top-level pane, put all its items directly            /* If there is just one top-level pane, put all its items directly
# Line 1259  digest_single_submenu (start, end, top_l Line 1268  digest_single_submenu (start, end, top_l
1268                  save_wv->next = wv;                  save_wv->next = wv;
1269                else                else
1270                  first_wv->contents = wv;                  first_wv->contents = wv;
1271                wv->name = pane_string;                wv->lname = pane_name;
1272                /* Ignore the @ that means "separate pane".                /* Set value to 1 so update_submenu_strings can handle '@'  */
1273                   This is a kludge, but this isn't worth more time.  */                wv->value = (char *) 1;
               if (!NILP (prefix) && wv->name[0] == '@')  
                 wv->name++;  
               wv->value = 0;  
1274                wv->enabled = 1;                wv->enabled = 1;
1275                wv->button_type = BUTTON_TYPE_NONE;                wv->button_type = BUTTON_TYPE_NONE;
1276                wv->help = Qnil;                wv->help = Qnil;
# Line 1287  digest_single_submenu (start, end, top_l Line 1293  digest_single_submenu (start, end, top_l
1293            selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);            selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
1294            help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);            help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
1295    
1296  #ifndef HAVE_MULTILINGUAL_MENU            if (STRINGP (item_name))
           if (STRING_MULTIBYTE (item_name))  
1297              {              {
1298                item_name = ENCODE_SYSTEM (item_name);                if (unicode_append_menu)
1299                    item_name = ENCODE_UTF_8 (item_name);
1300                  else if (STRING_MULTIBYTE (item_name))
1301                    item_name = ENCODE_SYSTEM (item_name);
1302    
1303                ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);                ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
1304              }              }
1305    
# Line 1299  digest_single_submenu (start, end, top_l Line 1308  digest_single_submenu (start, end, top_l
1308                descrip = ENCODE_SYSTEM (descrip);                descrip = ENCODE_SYSTEM (descrip);
1309                ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);                ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
1310              }              }
 #endif /* not HAVE_MULTILINGUAL_MENU */  
1311    
1312            wv = xmalloc_widget_value ();            wv = xmalloc_widget_value ();
1313            if (prev_wv)            if (prev_wv)
# Line 1307  digest_single_submenu (start, end, top_l Line 1315  digest_single_submenu (start, end, top_l
1315            else            else
1316              save_wv->contents = wv;              save_wv->contents = wv;
1317    
1318            wv->name = (char *) SDATA (item_name);            wv->lname = item_name;
1319            if (!NILP (descrip))            if (!NILP (descrip))
1320              wv->key = (char *) SDATA (descrip);              wv->lkey = descrip;
1321            wv->value = 0;            wv->value = 0;
1322            /* The EMACS_INT cast avoids a warning.  There's no problem            /* The EMACS_INT cast avoids a warning.  There's no problem
1323               as long as pointers have enough bits to hold small integers.  */               as long as pointers have enough bits to hold small integers.  */
# Line 1348  digest_single_submenu (start, end, top_l Line 1356  digest_single_submenu (start, end, top_l
1356    
1357    return first_wv;    return first_wv;
1358  }  }
1359    
1360    
1361    /* Walk through the widget_value tree starting at FIRST_WV and update
1362       the char * pointers from the corresponding lisp values.
1363       We do this after building the whole tree, since GC may happen while the
1364       tree is constructed, and small strings are relocated.  So we must wait
1365       until no GC can happen before storing pointers into lisp values.  */
1366    static void
1367    update_submenu_strings (first_wv)
1368         widget_value *first_wv;
1369    {
1370      widget_value *wv;
1371    
1372      for (wv = first_wv; wv; wv = wv->next)
1373        {
1374          if (wv->lname && ! NILP (wv->lname))
1375            {
1376              wv->name = SDATA (wv->lname);
1377    
1378              /* Ignore the @ that means "separate pane".
1379                 This is a kludge, but this isn't worth more time.  */
1380              if (wv->value == (char *)1)
1381                {
1382                  if (wv->name[0] == '@')
1383                    wv->name++;
1384                  wv->value = 0;
1385                }
1386            }
1387    
1388          if (wv->lkey && ! NILP (wv->lkey))
1389            wv->key = SDATA (wv->lkey);
1390    
1391          if (wv->contents)
1392            update_submenu_strings (wv->contents);
1393        }
1394    }
1395    
1396    
1397  /* Set the contents of the menubar widgets of frame F.  /* Set the contents of the menubar widgets of frame F.
1398     The argument FIRST_TIME is currently ignored;     The argument FIRST_TIME is currently ignored;
# Line 1516  set_frame_menubar (f, first_time, deep_p Line 1561  set_frame_menubar (f, first_time, deep_p
1561            if (NILP (string))            if (NILP (string))
1562              break;              break;
1563            wv->name = (char *) SDATA (string);            wv->name = (char *) SDATA (string);
1564              update_submenu_strings (wv->contents);
1565            wv = wv->next;            wv = wv->next;
1566          }          }
1567    
# Line 1729  w32_menu_show (f, x, y, for_click, keyma Line 1775  w32_menu_show (f, x, y, for_click, keyma
1775            char *pane_string;            char *pane_string;
1776            pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);            pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
1777            prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);            prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
1778  #ifndef HAVE_MULTILINGUAL_MENU  
1779            if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))            if (STRINGP (pane_name))
1780              {              {
1781                pane_name = ENCODE_SYSTEM (pane_name);                if (unicode_append_menu)
1782                    pane_name = ENCODE_UTF_8 (pane_name);
1783                  else if (STRING_MULTIBYTE (pane_name))
1784                    pane_name = ENCODE_SYSTEM (pane_name);
1785    
1786                ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);                ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
1787              }              }
1788  #endif  
1789            pane_string = (NILP (pane_name)            pane_string = (NILP (pane_name)
1790                           ? "" : (char *) SDATA (pane_name));                           ? "" : (char *) SDATA (pane_name));
1791            /* If there is just one top-level pane, put all its items directly            /* If there is just one top-level pane, put all its items directly
# Line 1784  w32_menu_show (f, x, y, for_click, keyma Line 1834  w32_menu_show (f, x, y, for_click, keyma
1834            selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);            selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
1835            help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);            help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
1836    
1837  #ifndef HAVE_MULTILINGUAL_MENU            if (STRINGP (item_name))
           if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))  
1838              {              {
1839                item_name = ENCODE_SYSTEM (item_name);                if (unicode_append_menu)
1840                    item_name = ENCODE_UTF_8 (item_name);
1841                  else if (STRING_MULTIBYTE (item_name))
1842                    item_name = ENCODE_SYSTEM (item_name);
1843    
1844                ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);                ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
1845              }              }
1846            if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))  
1847              if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1848              {              {
1849                descrip = ENCODE_SYSTEM (descrip);                descrip = ENCODE_SYSTEM (descrip);
1850                ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);                ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
1851              }              }
 #endif /* not HAVE_MULTILINGUAL_MENU */  
1852    
1853            wv = xmalloc_widget_value ();            wv = xmalloc_widget_value ();
1854            if (prev_wv)            if (prev_wv)
# Line 1844  w32_menu_show (f, x, y, for_click, keyma Line 1897  w32_menu_show (f, x, y, for_click, keyma
1897        wv_sep->next = first_wv->contents;        wv_sep->next = first_wv->contents;
1898        wv_sep->help = Qnil;        wv_sep->help = Qnil;
1899    
1900  #ifndef HAVE_MULTILINGUAL_MENU        if (unicode_append_menu)
1901        if (STRING_MULTIBYTE (title))          title = ENCODE_UTF_8 (title);
1902          else if (STRING_MULTIBYTE (title))
1903          title = ENCODE_SYSTEM (title);          title = ENCODE_SYSTEM (title);
1904  #endif  
1905        wv_title->name = (char *) SDATA (title);        wv_title->name = (char *) SDATA (title);
1906        wv_title->enabled = TRUE;        wv_title->enabled = TRUE;
1907        wv_title->title = TRUE;        wv_title->title = TRUE;
# Line 2150  add_left_right_boundary (HMENU menu) Line 2204  add_left_right_boundary (HMENU menu)
2204    return AppendMenu (menu, MF_MENUBARBREAK, 0, NULL);    return AppendMenu (menu, MF_MENUBARBREAK, 0, NULL);
2205  }  }
2206    
2207    /* UTF8: 0xxxxxxx, 110xxxxx 10xxxxxx, 1110xxxx, 10xxxxxx, 10xxxxxx */
2208    static void
2209    utf8to16 (unsigned char * src, int len, WCHAR * dest)
2210    {
2211      while (len > 0)
2212        {
2213          int utf16;
2214          if (*src < 0x80)
2215            {
2216              *dest = (WCHAR) *src;
2217              dest++; src++; len--;
2218            }
2219          /* Since we might get >3 byte sequences which we don't handle, ignore the extra parts.  */
2220          else if (*src < 0xC0)
2221            {
2222              src++; len--;
2223            }
2224          /* 2 char UTF-8 sequence.  */
2225          else if (*src <  0xE0)
2226            {
2227              *dest = (WCHAR) (((*src & 0x1f) << 6)
2228                               | (*(src + 1) & 0x3f));
2229              src += 2; len -= 2; dest++;
2230            }
2231          else if (*src < 0xF0)
2232            {
2233              *dest = (WCHAR) (((*src & 0x0f) << 12)
2234                               | ((*(src + 1) & 0x3f) << 6)
2235                               | (*(src + 2) & 0x3f));
2236              src += 3; len -= 3; dest++;
2237            }
2238          else /* Not encodable. Insert Unicode Substitution char.  */
2239            {
2240              *dest = (WCHAR) 0xfffd;
2241              src++; len--; dest++;
2242            }
2243        }
2244      *dest = 0;
2245    }
2246    
2247  static int  static int
2248  add_menu_item (HMENU menu, widget_value *wv, HMENU item)  add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2249  {  {
# Line 2206  add_menu_item (HMENU menu, widget_value Line 2300  add_menu_item (HMENU menu, widget_value
2300          fuFlags |= MF_UNCHECKED;          fuFlags |= MF_UNCHECKED;
2301      }      }
2302    
2303    return_value =    if (unicode_append_menu && out_string)
2304      AppendMenu (menu,      {
2305                  fuFlags,        /* Convert out_string from UTF-8 to UTF-16-LE.  */
2306                  item != NULL ? (UINT) item : (UINT) wv->call_data,        int utf8_len = strlen (out_string);
2307                  out_string );        WCHAR * utf16_string;
2308          if (fuFlags & MF_OWNERDRAW)
2309            utf16_string = local_alloc ((utf8_len + 1) * sizeof (WCHAR));
2310          else
2311            utf16_string = alloca ((utf8_len + 1) * sizeof (WCHAR));
2312    
2313          utf8to16 (out_string, utf8_len, utf16_string);
2314          return_value = unicode_append_menu (menu, fuFlags,
2315                                              item != NULL ? (UINT) item
2316                                                : (UINT) wv->call_data,
2317                                              utf16_string);
2318          if (fuFlags & MF_OWNERDRAW)
2319            local_free (out_string);
2320        }
2321      else
2322        {
2323          return_value =
2324            AppendMenu (menu,
2325                        fuFlags,
2326                        item != NULL ? (UINT) item : (UINT) wv->call_data,
2327                        out_string );
2328        }
2329    
2330    /* This must be done after the menu item is created.  */    /* This must be done after the menu item is created.  */
2331    if (!wv->title && wv->call_data != 0)    if (!wv->title && wv->call_data != 0)
# Line 2298  w32_menu_display_help (HWND owner, HMENU Line 2413  w32_menu_display_help (HWND owner, HMENU
2413        struct frame *f = x_window_to_frame (&one_w32_display_info, owner);        struct frame *f = x_window_to_frame (&one_w32_display_info, owner);
2414        Lisp_Object frame, help;        Lisp_Object frame, help;
2415    
2416        // No help echo on owner-draw menu items.        /* No help echo on owner-draw menu items.  */
2417        if (flags & MF_OWNERDRAW || flags & MF_POPUP)        if (flags & MF_OWNERDRAW || flags & MF_POPUP)
2418          help = Qnil;          help = Qnil;
2419        else        else
# Line 2422  void globals_of_w32menu () Line 2537  void globals_of_w32menu ()
2537    HMODULE user32 = GetModuleHandle ("user32.dll");    HMODULE user32 = GetModuleHandle ("user32.dll");
2538    get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");    get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
2539    set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");    set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
2540      unicode_append_menu = (AppendMenuW_Proc) GetProcAddress (user32, "AppendMenuW");
2541  }  }
2542    
2543  /* arch-tag: 0eaed431-bb4e-4aac-a527-95a1b4f1fed0  /* arch-tag: 0eaed431-bb4e-4aac-a527-95a1b4f1fed0

Legend:
Removed from v.1.68  
changed lines
  Added in v.1.69

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26