Re: [fltk.general] best way to get an int from Fl_Menu_Item user data
marty wrote: > long li = (long)v; works fine. Yes; this is a good option, everywhere *except* Win64... On Win64, a long is still only 32-bit (everyone else decided that in their 64-bit generation a long would be 64-bits, but MS decided they needed to preserve the sizeof(long) == sizeof(int) relationship that is assumed in the WIN32 API...) So, probably, fl_intptr_t is the more portable choice. Selex ES Ltd Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL A company registered in England & Wales. Company no. 02426132 This email and any attachments are confidential to the intended recipient and may also be privileged. If you are not the intended recipient please delete it from your system and notify the sender. You should not copy it or use it for any purpose nor disclose or distribute its contents to any other person. ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] best way to get an int from Fl_Menu_Item user data
On 04/03/13 13:22, marty moore wrote: > long i = (long)(w->argument()); compiles, but always results in '0'. > Doesn't w point back to the Fl_Menu_Button that had the menu? Probably depends on if you're setting the callback for the widget, or the callback for the items. Each item can have its own callback and userdata. Also, the Menu widget itself can also have its own callback + userdata. (The latter is used for items that have no callback of their own, IIRC.) If you're setting the callback for the widget, then w->userdata() should have any user_data() you'd set. But if you're setting the item's individual callbacks, then to access that item's userdata, your callback would have to first find the last item picked (with 'mvalue()') and then access its user_data(), eg: const Fl_Menu_Item *item = w->mvalue(); // get last picked item long i = (long)item->user_data(); // get user data for that item ..or something like that. ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] best way to get an int from Fl_Menu_Item user data
Hi, thanks for all the info! I really appreciate the response. I tried your suggestions on my system: Debian 6.5 (64 bit), gcc-4.4.5, emacs 23, fltk-1.3.2 I tested the following: eop op = (eop)fl_intptr_t(v); works fine int i = (int)v; fails to compile (loss of precision) like you all said. long li = (long)v; works fine. long i = (long)(w->argument()); compiles, but always results in '0'. Doesn't w point back to the Fl_Menu_Button that had the menu? I didn't set an argument in the Fl_Menu_Button. So, I'm going forward with fl_intptr_t, since it works and probally will work in the future. Thanks again, Marty ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] best way to get an int from Fl_Menu_Item user data
On 3 Apr 2013, at 19:38, Richard Sanders wrote: > When I first compiled with 64 bit linux the compiler complained about > > int i = (int)(v); > > > but was happy with > > long i = (long)(v); Greg's suggestion of using fl_intptr_t seems like the most portable option, should work *everywhere* I think! > > Both Linux and mingw 32 bit are happy with the change to long from > int. > > Mingw64 is another fish. AFAIK pointers in win64 are 64 bit pointers > and the compiler issues errors. The work around for that is to use the > compiler switch "fpermissive", then only warnings are issued. The *nix's (and VxWorks, others...) went from being ILP32, to being LP64, so in both those cases sizeof(long) == sizeof(ptr), but in the 64 bit cases sizeof(int) != sizeof(ptr). However, in an attempt to preserve as much as possible of their API, MS decided to go from ILP32 to LLP64/IL32, so that in Win64 code sizeof(long) != sizeof(ptr), you need to use sizeof(long long) == sizeof(ptr) Or... use intptr_t, since sizeof(intptr_t) == sizeof(ptr) everywhere... And of course sizeof(fl_intptr_t) == sizeof(ptr) everywhere too! > > Now in all cases long works so the same code covers all bets. Still think fl_intptr_t is the more portable solution long term. > Don't know about macs though. A Mac is just a *nix box these days... ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] best way to get an int from Fl_Menu_Item user data
On 3 Apr 2013, at 17:34, Greg Ercolano wrote: > On 04/03/13 08:44, marty moore wrote: >> I notice that old examples used >> int i = (int)v; >> but that won't work with gcc-4.4.5 > > Right -- probably a "precision loss" error during the void* -> int, > since sizeof(void*)==8 and sizeof(int)==4. > > I think the best approach (in 1.3.x) is to use the new fl_intptr_t, e.g. > > int i = fl_intptr_t(v); > > Or, you could just use a long instead of an int, but that might cause > trouble on non-64bit builds.. which is I think what fl_intptr_t tries > to solve. (See the definition in FL/Fl_Widget.H) Ah: right... Yes, I probably have -fpermissive set in my build environment anyway, so don't see this... I think something based around intptr_t (or fl_intptr_t) is the way to go, since on any host system, regardless of word size, that is "guaranteed" to provide an integral type that is large enough to hold a pointer... Probably intptr_t would work just about everywhere nowadays I'd guess, since C99 (and is it in C++11 too?) is pretty widely supported now. But the definition for fl_intptr_t should work *everywhere* so it is probably the most portable option. ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] best way to get an int from Fl_Menu_Item user data
On Wed, 03 Apr 2013 09:34:22 -0700, Greg Ercolano wrote: >> I notice that old examples used >> int i = (int)v; >> but that won't work with gcc-4.4.5 > > Right -- probably a "precision loss" error during the void* -> int, > since sizeof(void*)==8 and sizeof(int)==4. > > I think the best approach (in 1.3.x) is to use the new fl_intptr_t, e.g. > > int i = fl_intptr_t(v); > > Or, you could just use a long instead of an int, but that might cause > trouble on non-64bit builds.. which is I think what fl_intptr_t tries > to solve. (See the definition in FL/Fl_Widget.H) When I first compiled with 64 bit linux the compiler complained about int i = (int)(v); but was happy with long i = (long)(v); Both Linux and mingw 32 bit are happy with the change to long from int. Mingw64 is another fish. AFAIK pointers in win64 are 64 bit pointers and the compiler issues errors. The work around for that is to use the compiler switch "fpermissive", then only warnings are issued. Now in all cases long works so the same code covers all bets. Don't know about macs though. Cheers Richard ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] best way to get an int from Fl_Menu_Item user data
On 04/03/13 09:05, Ian MacArthur wrote: >> void mycallback(widget* w, void* v) { >> eop e = (eop) (atoi((char*)v)); > > What is it you are trying to do here? Probably trying to sidestep the 'precision loss' error from the newer compilers due to sizeof(void*) != sizeof(int). Using a char* is sizeof() compatible with a void*. This was kinda covered last year in STR #2813: http://www.fltk.org/str.php?L2813 > We might need to see your code. > Just tested with gcc 4.7.2 and that works fine... Might be a 32bit compile? I get the precision loss error when I build that example on 4.4.6 with a 64bit box: $ make foo2 Compiling foo2.cxx... foo2.cxx: In function 'void cb_item1(Fl_Menu_*, void*)': foo2.cxx:15: error: cast from 'void*' to 'int' loses precision make: *** [foo2.o] Error 1 ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] best way to get an int from Fl_Menu_Item user data
On 04/03/13 08:44, marty moore wrote: > I notice that old examples used > int i = (int)v; > but that won't work with gcc-4.4.5 Right -- probably a "precision loss" error during the void* -> int, since sizeof(void*)==8 and sizeof(int)==4. I think the best approach (in 1.3.x) is to use the new fl_intptr_t, e.g. int i = fl_intptr_t(v); Or, you could just use a long instead of an int, but that might cause trouble on non-64bit builds.. which is I think what fl_intptr_t tries to solve. (See the definition in FL/Fl_Widget.H) There is a "long Fl_Widget::argument()" method which would let you do: void mycallback(widget* w, void* v) { long li = w->argument(); [..] ..but again, I think you'd loose on a 32bit build when doing the long->void* cast. Which is why I think the fl_intptr_t is probably the best way to go. While dicking around, of interest I found this also seems to evade the precision loss error, not completely sure why: void foo(Fl_Widget *w, void *v) { int i = (int)(long)(v); [..] > Should this be covered in a tutorial? Probably -- I don't think fl_intptr_t is even documented yet (it has a 'todo' signifier), but it's defined in Fl_Widget.H and used in some of the examples, like test/tree.cxx. ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] best way to get an int from Fl_Menu_Item user data
Assuming this is readable this time... (and not more B64 nonsense...) > I'm looking at storing an enum as user data in an Fl_Menu_Item user > data. In the callback, I want to access the enum. > > I know that I can put the enum into user data as a string: > enum eop { task0=200, task2, task3}; > > Fl_Menu_Item menu = { > { "thing 1", 0, mycallback, (void*)"201"} } > void mycallback(widget* w, void* v) > { > eop e = (eop) (atoi((char*)v)); > ... > } What is it you are trying to do here? Pass a numeric value into the callback in the userdata, I think; but you are doing it by passing a string than calling atoi() on it... > but that seems a little cumbersome and inflexable. Indeed. Worked example below. > I notice that old examples used > int i = (int)v; > but that won't work with gcc-4.4.5 Huh? Should do. We might need to see your code. Just tested with gcc 4.7.2 and that works fine... > Will fltk-3 provide more flexibility? No, it is the same. For now, fltk-1.3 is the recommended build, it is stable. Fltk3 less so... // // fltk-config --compile menu-userdata.cxx // #include #include #include #include static Fl_Double_Window *main_win=(Fl_Double_Window *)0; static Fl_Menu_Bar *menu_bar=(Fl_Menu_Bar *)0; enum eop { task0=200, task2, task3}; static void cb_item1(Fl_Menu_*, void *v) { int i = (int)v; printf("Menu got %d\n", i); fflush(stdout); } Fl_Menu_Item menu_menu_bar[] = { {"A Menu", 0, 0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0}, {"Item 1", 0, (Fl_Callback*)cb_item1, (void *)task0, 0, FL_NORMAL_LABEL, 0, 14, 0}, {"Item 2", 0, (Fl_Callback*)cb_item1, (void *)task2, 0, FL_NORMAL_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0} }; int main(int argc, char **argv) { { main_win = new Fl_Double_Window(356, 231, "Test Window"); { menu_bar = new Fl_Menu_Bar(0, 0, 356, 20); menu_bar->menu(menu_menu_bar); } // Fl_Menu_Bar* menu_bar main_win->end(); } // Fl_Double_Window* main_win main_win->show(argc, argv); return Fl::run(); } / end of file /// ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk