Get colour from event ColourDbox_ColourSelected
Michael Gerbracht (180) 104 posts |
I am trying to get the selected colour from the toolbox event ColourDbox_ColourSelected (0×829c2). I am using the toolbox library (not OSLib) and the event is defined as: typedef struct { ToolboxEventHeader hdr; unsigned int colour_block[(212/4)]; } ColourDboxColourSelectedEvent;What I first tried was the following: int handle_colour_selected_event(int event_code, ToolboxEvent event, IdBlock *id_block, void *handle) } But I now think that the int value is not the colour but a pointer to the colour block. But I am still not sure how exactly I can get the colour. Do I need to define my own struct for the colour_block? Unfortunately the manual is not very crear to me here. |
Julie Stamp (8365) 474 posts |
I think the colour is the first word of colour_block. The manual says it’s stored as &RRGGBB00. On the other hand the OSLib StrongHelp manual implies it’s stored as &BBGRR00. Perhaps you could let us know which way round it turns out to be? |
Michael Gerbracht (180) 104 posts |
Ok, the strange thing is: I always get the same integer when I receive the event – no matter what colour is selected and whether “none” is selected or not. The value is 46080 (= 0xb400). (once I manage to get a colour I will have a look which order is correct) |
Andrew Conroy (370) 740 posts |
I’ve just done a quick test in BASIC on a Pi3B+, and it’s &BBGGRR00 |
Andy S (2979) 504 posts |
First you seem to be missing a star inside the brackets on this line: colour_event = (ColourDboxColourSelectedEvent) event; This is what I found digging around in the source code, but these are uneducated guesses as I haven’t used Toolbox. typedef struct { char nought; /* = 0 */ char blue; char green; char red; int extension_size; } ColourDescriptorHeader; It seems to me, looking at the source for event_picker_choice(), that your ColourDboxColourSelectedEvent is populated with data from a colourpicker_PickerChoice structure: ColourDbox_ColourSelected_Event *colour_selected = (ColourDbox_ColourSelected_Event *) &toolbox_event; ColourPicker_PickerChoice_Event *picker_choice = (ColourPicker_PickerChoice_Event *) block; /* raise the toolbox event ColourDbox_ColourSelected _if_ the client has asked to be informed of this */ memcpy (&colour_selected->hdr.flags, &picker_choice->message.flags, picker_choice->message.colour_descriptor_block.hdr.extension_size + sizeof (ColourDescriptorHeader) + sizeof(int)); That structure is defined as follows: typedef struct { int dialogue_handle; int flags; struct { ColourDescriptorHeader hdr; struct { unsigned int model; /* This extension caters fully for only three models */ union { struct { int red; /* % */ int green; /* % */ int blue; /* % */ } rgb; struct { int cyan; /* % */ int magenta; /* % */ int yellow; /* % */ int key; /* % */ } cmyk; struct { int hue; /* angle (degrees) */ int saturation; /* % */ int value; /* % */ } hsv; char bytes[256-sizeof(wimp_MsgHdr)-sizeof(ColourDescriptorHeader)-sizeof(int)]; int words[(256-sizeof(wimp_MsgHdr)-sizeof(ColourDescriptorHeader)-sizeof(int))/4]; } data; } colour_model; } colour_descriptor_block; } colourpicker_PickerChoice, colourpicker_ColourChanged; typedef struct { wimp_MsgHdr hdr; colourpicker_PickerChoice message; } ColourPicker_PickerChoice_Event; Looking at the memcpy(), I don’t think your colour_block contains the dialogue_handle, I think you have It’s late and I don’t even know for sure that this code applies to the event you’re receiving, but maybe it will be of some use. EDIT: I rewrote most of the post when I found some different code. I also notice that the ColourDbox_ColourSelected_Event struct I found in the above source is named differently, with underscores, to the one you have. However, looking at the headers the two versions have identical definitions. |
Michael Gerbracht (180) 104 posts |
Thanks Andy! First: The star is there – that’s why the bold text in my first post ends there – sorry I have to learn how to quote code correctly here in the forum. Ok, the ColourDboxColourSelectedEvent contains two “items”: the ToolboxEventHeader “hdr” and an unsigned int “colour_block”. So I was expecting the colour to be in the colour_block in analogy to e.g. factor in the scale event. But it seems that it is in the header. I am still wondering what value the unsigned int colour_block contains? In the source code where the toolbox event is rizen I do not see that it is being set. |
Steve Drain (222) 1620 posts |
I cannot comment on the C, but in BASIC the event block is returned as an event header of 4 words followed by the colour block. The first word of the colour block, |
Andy S (2979) 504 posts |
No it wouldn’t be in colour_event->hdr . It should be in the colour_block. I think that memcpy() code I posted only copies flags into colour_event->hdr.flags and then everything else, the ColourDescriptorHeader and colour data, is past the end of hdr inside the colour_block.
As Steve and Andrew are both saying the colour is in the first word of the colour block, see if this gives you the colour: |
Michael Gerbracht (180) 104 posts |
Thanks Andy, it works now as expected. This memory copy thing is something I have to get used to. If you are coming from other languages this seems very strange but I think I understand now what is happening. |
Andy S (2979) 504 posts |
I agree it’s not greatly intuitive, especially in the code I posted where they’re copying between two different structures and the destination struct contains an array of (likely undocumented) ints. Of course it comes from a time when speed and efficiency mattered above all else. Code readability was a far lesser consideration. Most of us are really grateful for how tight and efficient RISC OS is, but sometimes the extra hours us programmers spend grappling with all the low-level, cryptic code does make us question it. Really glad you got it working. |