Re: [fltk.general] best way to get an int from Fl_Menu_Item user data

2013-04-04 Thread MacArthur, Ian (Selex ES, UK)
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

2013-04-03 Thread Greg Ercolano
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

2013-04-03 Thread marty moore
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

2013-04-03 Thread Ian MacArthur

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

2013-04-03 Thread Ian MacArthur

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

2013-04-03 Thread Richard Sanders
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

2013-04-03 Thread Greg Ercolano
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

2013-04-03 Thread Greg Ercolano
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

2013-04-03 Thread Ian MacArthur
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