Integrating GfxLib with Gtk

Linux specific questions.
caseih
Posts: 1064
Joined: Feb 26, 2007 5:32

Integrating GfxLib with Gtk

Postby caseih » Feb 27, 2007 2:57

forum admins, feel free to move this post to another forum if it's more appropriate there. This is a linux-based thing (should work on win32 with gtk though), but whatever.

I've written a quick and dirty demonstration, a la the win32 demo in the language reference, on painting the ScreenPtr to a GtkDrawingArea widget. Now it sort of works, but currently the byte ordering of the ScreenPtr is not what the GdkPixbuf wrapper is expecting, so while you can see the letters on the screen that where PRINTed there, drawing lines and stuff is funky. And there's no real provision for redrawing the screen other than on an expose. But here's the code. It has no real purpose, but others may enjoy it. The window starts off with a DrawingArea that's 0 pixels, so you'll have to resize the window.

Here's the glade file:

Code: Select all

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="GtkWindow" id="window">
  <property name="visible">True</property>
  <property name="title" translatable="yes">FreeBASIC and GTK and GfxLib</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <property name="decorated">True</property>
  <property name="skip_taskbar_hint">False</property>
  <property name="skip_pager_hint">False</property>
  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
  <property name="focus_on_map">True</property>
  <property name="urgency_hint">False</property>
  <signal name="delete_event" handler="on_window_delete_event" last_modification_time="Mon, 26 Feb 2007 06:16:11 GMT"/>

  <child>
    <widget class="GtkVBox" id="vbox1">
      <property name="border_width">11</property>
      <property name="visible">True</property>
      <property name="homogeneous">False</property>
      <property name="spacing">5</property>

      <child>
   <widget class="GtkDrawingArea" id="drawingarea1">
     <property name="visible">True</property>
     <signal name="configure_event" handler="on_drawingarea_configure_event" last_modification_time="Mon, 26 Feb 2007 05:55:48 GMT"/>
     <signal name="expose_event" handler="on_drawingarea_expose_event" last_modification_time="Mon, 26 Feb 2007 05:55:56 GMT"/>
   </widget>
   <packing>
     <property name="padding">0</property>
     <property name="expand">True</property>
     <property name="fill">True</property>
   </packing>
      </child>

      <child>
   <widget class="GtkHBox" id="hbox1">
     <property name="border_width">10</property>
     <property name="visible">True</property>
     <property name="homogeneous">False</property>
     <property name="spacing">0</property>

     <child>
       <widget class="GtkButton" id="quit_button">
         <property name="visible">True</property>
         <property name="can_focus">True</property>
         <property name="label">gtk-quit</property>
         <property name="use_stock">True</property>
         <property name="relief">GTK_RELIEF_NORMAL</property>
         <property name="focus_on_click">True</property>
         <signal name="clicked" handler="on_quit_button_clicked" last_modification_time="Mon, 26 Feb 2007 05:58:55 GMT"/>
       </widget>
       <packing>
         <property name="padding">0</property>
         <property name="expand">False</property>
         <property name="fill">False</property>
         <property name="pack_type">GTK_PACK_END</property>
       </packing>
     </child>

     <child>
       <widget class="GtkButton" id="button2">
         <property name="visible">True</property>
         <property name="can_focus">True</property>
         <property name="label" translatable="yes">button2</property>
         <property name="use_underline">True</property>
         <property name="relief">GTK_RELIEF_NORMAL</property>
         <property name="focus_on_click">True</property>
         <signal name="clicked" handler="on_button2_clicked" last_modification_time="Mon, 26 Feb 2007 05:58:42 GMT"/>
       </widget>
       <packing>
         <property name="padding">0</property>
         <property name="expand">False</property>
         <property name="fill">False</property>
         <property name="pack_type">GTK_PACK_END</property>
       </packing>
     </child>

     <child>
       <widget class="GtkButton" id="button3">
         <property name="visible">True</property>
         <property name="can_focus">True</property>
         <property name="label" translatable="yes">button3</property>
         <property name="use_underline">True</property>
         <property name="relief">GTK_RELIEF_NORMAL</property>
         <property name="focus_on_click">True</property>
         <signal name="clicked" handler="on_button3_clicked" last_modification_time="Mon, 26 Feb 2007 05:58:48 GMT"/>
       </widget>
       <packing>
         <property name="padding">0</property>
         <property name="expand">False</property>
         <property name="fill">False</property>
         <property name="pack_type">GTK_PACK_END</property>
       </packing>
     </child>
   </widget>
   <packing>
     <property name="padding">0</property>
     <property name="expand">False</property>
     <property name="fill">False</property>
   </packing>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>

Here's the bas file:

Code: Select all

option explicit 'no idea what this does
defint a-z

#include "gtk/gtk.bi"
#include "gtk/libglade/glade-xml.bi"
#include "fbgfx.bi"

#define NULL 0
dim shared w,h
dim shared xml as GladeXML Ptr


declare sub on_window_delete_event cdecl alias _
           "on_window_delete_event" ( byval object as GtkObject Ptr, _
                                 byval user_data as gpointer )
declare sub on_drawingarea_configure_event cdecl alias _
           "on_drawingarea_configure_event" ( byval object as GtkObject Ptr, _
                                       byval event as GdkEventConfigure Ptr, _
                                         byval user_data as gpointer )
declare sub on_drawingarea_expose_event cdecl alias _
           "on_drawingarea_expose_event" ( byval object as GtkObject Ptr, _
                                           byval expose as GdkEventExpose Ptr, _
                                      byval user_data as gpointer )
declare sub on_quit_button_clicked cdecl alias _
           "on_quit_button_clicked" ( byval object as GtkObject Ptr, _
                                 byval user_data as gpointer )
declare sub on_button2_clicked cdecl alias _
           "on_button2_clicked" ( byval object as GtkObject Ptr, _
                             byval user_data as gpointer )
declare sub on_button3_clicked cdecl alias _
           "on_button3_clicked" ( byval object as GtkObject Ptr, _
                             byval user_data as gpointer )

sub redraw ()
   dim widget as GtkWidget Ptr

   widget=glade_xml_get_widget(xml,"drawingarea")
   gtk_widget_queue_draw_area(widget,0,0,w,h)
end sub

sub on_window_delete_event cdecl ( byval object as GtkObject Ptr, _
                               byval user_data as gpointer )
   on_quit_button_clicked(object,user_data)
end sub

sub on_quit_button_clicked cdecl ( byval object as GtkObject Ptr, _
                              byval user_data as gpointer ) export
   print "Quit Button clicked."
   gtk_main_quit()
end sub

sub on_button3_clicked cdecl ( byval object as GtkObject Ptr, _
                          byval user_data as gpointer )

   print "Button 3 clicked"
   line (40,40)-(139,499),55
   redraw
end sub

sub on_drawingarea_configure_event cdecl ( byval object as GtkObject Ptr, _
                                       byval event as GdkEventConfigure Ptr, _
                                      byval user_data as gpointer )

   w=event->width
   h=event->height
   
   print "New dimensions are ";w;",";h
   if h < 16 or w < 16 then print "too small" : return
   ScreenRes w,h,24,1,GFX_NULL
   width ,25
   color ,0
   cls
   print "Drawing area (re)configured."
   print "New dimensions are ";w;",";h

   'here we resize the screen buffer


end sub

sub on_drawingarea_expose_event cdecl ( byval object as GtkObject Ptr, _
                                        byval expose as GdkEventExpose Ptr, _
                                   byval user_data as gpointer )

   dim pixbuf as GdkPixbuf Ptr
   dim gc as GdkGC Ptr

   if h < 16 or w < 16 then print "too small; no drawing" : return 'no valid graphics mode yet

   pixbuf=gdk_pixbuf_new_from_data(ScreenPtr, _
                                   GDK_COLORSPACE_RGB, _
               0, _
               8, _
               w, _
               h, _
               w*4, _
               NULL, _
               NULL)
   gc = gdk_gc_new (expose->window)

   gdk_pixbuf_render_to_drawable (pixbuf, _
                                  expose->window, _
                   gc, _
                   0,0,0,0, _
                   w,h, _
                   GDK_RGB_DITHER_NORMAL, _
                   0,0)

   gdk_pixbuf_unref(pixbuf)
   gdk_gc_unref(gc)
end sub

dim window_widget as GtkWidget Ptr

gtk_init( NULL, NULL)
xml = glade_xml_new("gtkgfxlib.glade",NULL,NULL)

window_widget=glade_xml_get_widget( xml, "window")
gtk_widget_show_all( window_widget)
gtk_widget_set_size_request (glade_xml_get_widget(xml,"drawingarea"), 640, 480)
glade_xml_signal_autoconnect(xml)
gtk_main()

end 0
tunginobi
Posts: 655
Joined: Jan 10, 2006 0:44
Contact:

Postby tunginobi » Feb 27, 2007 5:58

Very nice! Got it working after a few tweaks:

1. The forum [ code ] tags have changed SYSTEM into System and name= to Name in the Glade XML file.
2. In two places in the source, you refer to "drawingarea", but the widget is named "drawingarea1".
3. You haven't written the implementation of on_button2_clicked().
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Feb 27, 2007 9:12

it doesn't appear to work on windows(2k), i get this dumped out to a console:

(thing.exe:792): Gtk-CRITICAL **: gtk_widget_set_size_request: assertion `GTK_IS_WIDGET (widget)' failed

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_button2_clicked'.

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_window_delete_event'.

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_drawingarea_configure_event'.

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_button3_clicked'.

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_drawingarea_expose_event'.


looks lkie this when running:

Image

that isn't correct, is it?
caseih
Posts: 1064
Joined: Feb 26, 2007 5:32

Postby caseih » Feb 27, 2007 20:05

cha0s wrote:it doesn't appear to work on windows(2k), i get this dumped out to a console:

(thing.exe:792): Gtk-CRITICAL **: gtk_widget_set_size_request: assertion `GTK_IS_WIDGET (widget)' failed

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_button2_clicked'.

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_window_delete_event'.

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_drawingarea_configure_event'.

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_button3_clicked'.

(thing.exe:792): libglade-WARNING **: could not find signal handler 'on_drawingarea_expose_event'.



As for the first warning, I was having a problem getting the drawing area to have an initial size. I never did solve that one, hence the warning, which can be ignored in this case.

The auto signal connect subroutine likely does not work on windows. It relies on features of the gnu linker that are only available on elf binaries. Signals would have to be connected by hand. To do this you would extract a pointer to each widget and connect that widget's appropriate signal to the signal handler.
caseih
Posts: 1064
Joined: Feb 26, 2007 5:32

Postby caseih » Feb 27, 2007 20:09

tunginobi wrote:Very nice! Got it working after a few tweaks:

1. The forum [ code ] tags have changed SYSTEM into System and name= to Name in the Glade XML file.
2. In two places in the source, you refer to "drawingarea", but the widget is named "drawingarea1".
3. You haven't written the implementation of on_button2_clicked().



Hmm. My code was running, so maybe I changed the glade file sometime after I built the exe the first time.

As for the other handler, this is true. I figured I would make it draw circles at some point or something. The Gtk warning about not finding the handler is harmless. That's the nice thing about signals. They can be emitted to their hearts content even if no one is around to listen to them.

You are seeing the color problems, right? The order of the bytes in the screen buffer still need to be worked out. Maybe it would be nice if ScreenRes could allow you to tweak the byte order, say to just make it RRRRGGGGBBBB, instead of some 4-byte thing that the 24-bit screen defaults too.
tunginobi
Posts: 655
Joined: Jan 10, 2006 0:44
Contact:

Postby tunginobi » Feb 27, 2007 23:07

caseih wrote:You are seeing the color problems, right? The order of the bytes in the screen buffer still need to be worked out. Maybe it would be nice if ScreenRes could allow you to tweak the byte order, say to just make it RRRRGGGGBBBB, instead of some 4-byte thing that the 24-bit screen defaults too.


Yeah, I noticed when I started using the rgb() macro to draw circles and such.

FB's GTK headers only include the one byte order:

Code: Select all

Enum GdkColorspace
   GDK_COLORSPACE_RGB
end Enum
caseih
Posts: 1064
Joined: Feb 26, 2007 5:32

Postby caseih » Feb 28, 2007 5:12

EDIT: Fixed the expose handler. Apparently the bytes were in RGBA order

I added a hack to adjust the bytes so GTK is happy. It proves this works anyway. Button2 and button3 now do things like drawing random stuff.

Note that since ScreenPtr is painted manually, or when the window is exposed, you can't just do things like "input a$" without gtk freezing up while you are doing it (and you won't see anything!)

To really make this usable, we'd have to do complicated threading to make sure that "input a$" wouldn't block the gui AND update stuff. This is complicated by the fact that GTK wants to be in charge of events and all that so any basic code is likely run from within a GTK call-back. But as long as you don't want to do any BASIC-style input, this could be useful to someone.

Code: Select all

option explicit 'no idea what this does
defint a-z

#include "gtk/gtk.bi"
#include "gtk/libglade/glade-xml.bi"
#include "fbgfx.bi"

#define NULL 0
dim shared w,h
dim shared xml as GladeXML Ptr
dim shared gtkbuffer as zstring ptr

gtkbuffer = NULL

declare sub on_window_delete_event cdecl alias _
           "on_window_delete_event" ( byval object as GtkObject Ptr, _
                                 byval user_data as gpointer )
declare sub on_drawingarea_configure_event cdecl alias _
           "on_drawingarea_configure_event" ( byval object as GtkObject Ptr, _
                                       byval event as GdkEventConfigure Ptr, _
                                         byval user_data as gpointer )
declare sub on_drawingarea_expose_event cdecl alias _
           "on_drawingarea_expose_event" ( byval object as GtkObject Ptr, _
                                           byval expose as GdkEventExpose Ptr, _
                                      byval user_data as gpointer )
declare sub on_quit_button_clicked cdecl alias _
           "on_quit_button_clicked" ( byval object as GtkObject Ptr, _
                                 byval user_data as gpointer )
declare sub on_button2_clicked cdecl alias _
           "on_button2_clicked" ( byval object as GtkObject Ptr, _
                             byval user_data as gpointer )
declare sub on_button3_clicked cdecl alias _
           "on_button3_clicked" ( byval object as GtkObject Ptr, _
                             byval user_data as gpointer )

sub redraw ()
   dim widget as GtkWidget Ptr

   widget=glade_xml_get_widget(xml,"drawingarea1")
   gtk_widget_queue_draw_area(widget,0,0,w,h)
end sub

sub on_window_delete_event cdecl ( byval object as GtkObject Ptr, _
                               byval user_data as gpointer )
   on_quit_button_clicked(object,user_data)
end sub

sub on_quit_button_clicked cdecl ( byval object as GtkObject Ptr, _
                              byval user_data as gpointer ) export
   print "Quit Button clicked."
   redraw
   gtk_main_quit()
end sub

sub on_button2_clicked cdecl ( byval object as GtkObject Ptr, _
                          byval user_data as gpointer )

   color ,rnd(1)*&hffffff
   print "Button 2 clicked"

   dim x,y,c,r,f
   x=rnd(1)*w
   y=rnd(1)*h
   r=rnd(1)*(w+h)/3
   c=rnd(1)*&hffffff
   f=rnd(1)*10

   if f>5 then
      circle (x,y),r,c
   else
      circle (x,y),r,c,,,,F
   end if
   redraw
end sub


sub on_button3_clicked cdecl ( byval object as GtkObject Ptr, _
                          byval user_data as gpointer )

   color ,rnd(1)*&hffffff
   print "Button 3 clicked"

   dim x,y,a,b,c,f
   x=rnd(1)*w
   y=rnd(1)*h
   a=rnd(1)*w
   b=rnd(1)*h
   c=rnd(1)*&hffffff
   f=rnd(1)*10

   if f>5 then
      line (x,y)-(a,b),c
   else
      line (x,y)-(a,b),c,bf
   end if
   redraw
end sub

sub on_drawingarea_configure_event cdecl ( byval object as GtkObject Ptr, _
                                       byval event as GdkEventConfigure Ptr, _
                                      byval user_data as gpointer )

   w=event->width
   h=event->height
   
   if gtkbuffer <> NULL then deallocate(gtkbuffer):gtkbuffer=NULL

   print "New dimensions are ";w;",";h
   if h < 16 or w < 16 then print "too small" : return
   ScreenRes w,h,24,1,GFX_NULL
   gtkbuffer = allocate(w*h*3)
   width ,25
   color ,0
   cls
   print "Drawing area (re)configured."
   print "New dimensions are ";w;",";h

   'here we resize the screen buffer


end sub

sub on_drawingarea_expose_event cdecl ( byval object as GtkObject Ptr, _
                                        byval expose as GdkEventExpose Ptr, _
                                   byval user_data as gpointer )

   dim pixbuf as GdkPixbuf Ptr
   dim gc as GdkGC Ptr
   dim c as zstring ptr
   dim d as zstring ptr
   dim x

   if h < 16 or w < 16 then print "too small; no drawing" : return 'no valid graphics mode yet

   c = ScreenPtr
   d = gtkbuffer

   for x=0 to h*w-1
      *d=*c
      c = c + 1
      d = d + 1
      *d=*c
      c = c + 1
      d = d + 1
      *d=*c
      c = c + 1
      d = d + 1
      c = c + 1
   next
      

   pixbuf=gdk_pixbuf_new_from_data(gtkbuffer, _
                                   GDK_COLORSPACE_RGB, _
               0, _
               8, _
               w, _
               h, _
               w*3, _
               NULL, _
               NULL)
   gc = gdk_gc_new (expose->window)

   gdk_pixbuf_render_to_drawable (pixbuf, _
                                  expose->window, _
                   gc, _
                   0,0,0,0, _
                   w,h, _
                   GDK_RGB_DITHER_NORMAL, _
                   0,0)

   gdk_pixbuf_unref(pixbuf)
   gdk_gc_unref(gc)
end sub

dim window_widget as GtkWidget Ptr

randomize

gtk_init( NULL, NULL)
xml = glade_xml_new("gtkgfxlib.glade",NULL,NULL)

window_widget=glade_xml_get_widget( xml, "window")
gtk_widget_show_all( window_widget)
gtk_widget_set_size_request (glade_xml_get_widget(xml,"drawingarea1"), 640, 480)
glade_xml_signal_autoconnect(xml)
gtk_main()

end 0

Last edited by caseih on Feb 28, 2007 5:39, edited 1 time in total.
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Feb 28, 2007 5:17

Can you show me how to make this work the "right" way, so that it's crossplatform?
caseih
Posts: 1064
Joined: Feb 26, 2007 5:32

Postby caseih » Feb 28, 2007 5:46

First add

Code: Select all

#include "gtk/glib.bi"


Then you'll have to replace the xml autoconnect lines with:

Code: Select all

g_signal_connect(glade_xml_get_widget(xml,"window"), "delete-event", @on_window_delete_event,NULL)

g_signal_connect(glade_xml_get_widget(xml,"drawingarea1"), "configure-event", @on_drawingarea_configure_event,NULL)

g_signal_connect(glade_xml_get_widget(xml,"drawingarea1"), "expose-event", @on_drawingarea_expose_event,NULL)

g_signal_connect(glade_xml_get_widget(xml,"quit_button"), "clicked", @on_quit_button_clicked,NULL)

g_signal_connect(glade_xml_get_widget(xml,"button2_button"), "clicked", @on_button2_button_clicked,NULL)

g_signal_connect(glade_xml_get_widget(xml,"button3_button"), "clicked", @on_button3_button_clicked,NULL)



I think that does it. I still am having byte order problems. I think GTK and FB must be opposite each other or something.
caseih
Posts: 1064
Joined: Feb 26, 2007 5:32

Postby caseih » Feb 28, 2007 5:52

For linux, the proper byte copying code from the expose handler is:

Code: Select all

   for x=0 to h*w-1
      *d=*(c+2)
      c = c + 1
      d = d + 1
      *d=*c
      c = c + 1
      d = d + 1
      *d=*(c-2)
      c = c + 1
      d = d + 1
      c = c + 1
   next
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Feb 28, 2007 8:10

Nice, I got it to work, I had to change these lines:

Code: Select all

g_signal_connect(glade_xml_get_widget(xml,"button2"), "clicked", @on_button2_clicked,NULL)
g_signal_connect(glade_xml_get_widget(xml,"button3"), "clicked", @on_button3_clicked,NULL)


i got a lot of warnings though, i followed it back:

#define g_signal_connect(i,s,h,d) g_signal_connect_data(i,s,h,d,0,0)
declare function g_signal_connect_data (byval instance as gpointer, byval detailed_signal as zstring ptr, byval c_handler as GCallback, byval data as gpointer, byval destroy_data as GClosureNotify, byval connect_flags as GConnectFlags) as gulong
#define G_CALLBACK(f) (cast(GCallback,f))
type GCallback as sub cdecl()

so... it's expecting a cdecl sub with no parameters... i wonder if that's wrong...
caseih
Posts: 1064
Joined: Feb 26, 2007 5:32

Postby caseih » Feb 28, 2007 16:32

I'm really good about posting code with "some assembly required" aren't I? :)

Yes the function pointer should be wrapped in the G_CALLBACK casting macro. It's okay that it expects a cdecl with no parameters. That's because each signal has a different signature, or number of parameters to pass to a callback. Being cdecl, it just won't matter. Hence the macro which casts everything to a cdecl with no params.
owen
Posts: 433
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

Re: Integrating GfxLib with Gtk

Postby owen » Aug 20, 2016 4:42

How does this work?
Does the for next loop affect gtkbuffer?
Only thing I can tell is it affect C and D which are not used in any of the code below the for next loop.
gtkbuffer appears to be unchanged and the image is the same.
I can not compile and test this as I am having a hard time getting GTK2 and Glade to work.
i have FB 1.05 and GTK 3.8.2 up and running but this was written for gtk2 i think.
if anybody can compile and let me know if it works please let me know.

Code: Select all

   c = ScreenPtr
   d = gtkbuffer

   for x=0 to h*w-1
      *d=*c
      c = c + 1
      d = d + 1
      *d=*c
      c = c + 1
      d = d + 1
      *d=*c
      c = c + 1
      d = d + 1
      c = c + 1
   next
     

   pixbuf=gdk_pixbuf_new_from_data(gtkbuffer, _
                                   GDK_COLORSPACE_RGB, _
               0, _
               8, _
               w, _
               h, _
               w*3, _
               NULL, _
               NULL)
   gc = gdk_gc_new (expose->window)

   gdk_pixbuf_render_to_drawable (pixbuf
owen
Posts: 433
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

Re: Integrating GfxLib with Gtk

Postby owen » Aug 24, 2016 3:12

i use gtk image new from file to load a bit map
i wonder if there's a way to create a gtk image without having to load it from an file, data, pixbub etc ?
myimage = gtk_image_new_from_file("580x580-black.bmp")
myimage = gtk_blank_image(width,height)

any how this is how i have managed to make fb graphics (fbgfx) work in gtk3
sure wish there was a way to not have to iterate through each pixel
For i = 0 To mywidth*myheight-1
*(mygetpixels+i*3)=myrgb.r
*(mygetpixels+i*3+1)=myrgb.g
*(mygetpixels+i*3+2)=myrgb.b
Next
wish instead i could just say something like *(mygetpixels = *modifiedscreenptr



Code: Select all

'fbcad drawarea width and height = 581 (0 to 580)
'screenres 581,581
'using widths and heights not multiples of 4 does'nt work
'use 580x580

Declare Sub myfbgfxtogtkimg()
Declare Sub mymain()
Declare Sub mygfxcolors()
Declare Sub moreballs()
Declare Sub lessballs()
Declare Sub myrgbcol(pc As UByte)


#include "fbgfx.bi"
#DEFINE __USE_GTK3__
#include once "gtk/gtk.bi"
#LIBPATH "c:/gtk3/lib"

#Define NULL 0

Dim Shared As GtkWidget Ptr win
Dim Shared As GtkWidget Ptr fixed
Dim As GtkWidget Ptr button1
Dim As GtkWidget Ptr button2
Dim Shared As GtkWidget Ptr myimage
Dim Shared mypixbuf as GdkPixbuf Ptr
Dim Shared mygetpixels As UByte Ptr
Dim Shared mywidth As Integer
Dim Shared myheight As Integer

Type myclr
    r As UByte
    g As UByte
    b As UByte
End Type
Dim Shared myrgb As myclr


Dim Shared ballc As Integer


gtk_init(NULL, NULL)

win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_title(GTK_WINDOW(win), "FBgfx and GTK3image by Owen")
gtk_widget_set_size_request(win, 700, 700)


fixed = gtk_fixed_new()
gtk_container_add(GTK_CONTAINER(win), fixed)
 
button1 = gtk_button_new_with_label("More balls")
gtk_widget_set_size_request(button1, 80, 35)
gtk_fixed_put(GTK_FIXED(fixed), button1, 10, 50)
g_signal_connect(G_OBJECT(button1), "clicked", G_CALLBACK (@moreballs), NULL)

button2 = gtk_button_new_with_label("Less balls")
gtk_widget_set_size_request(button2, 80, 35)
gtk_fixed_put(GTK_FIXED(fixed), button2, 10, 100)
g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK (@lessballs), NULL)

g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK (@gtk_main_quit), NULL)

'for fbgfx---------
myimage = gtk_image_new_from_file("580x580-black.bmp")
mypixbuf=gtk_image_get_pixbuf(myimage)
mygetpixels=gdk_pixbuf_get_pixels (mypixbuf)
mywidth = gdk_pixbuf_get_width (mypixbuf)
myheight = gdk_pixbuf_get_height (mypixbuf)
'gtk image to display fbgfx
gtk_fixed_put(fixed, myimage, 100, 50)


'when gtk is idle - draw the ball
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, @mymain, NULL, NULL)

'ScreenRes 581,581,,1,fb.GFX_NULL
ScreenRes mywidth,myheight,,1',fb.GFX_NULL

ballc=2
Dim Shared As Integer ball(4096,4)'x,y,direction,color
Dim As Integer i
For i = 1 To 4096
   ball(i,1)=Int(Rnd*(mywidth-11))+11
   ball(i,2)=Int(Rnd*(myheight-11))+11
   ball(i,3)=Int(Rnd*7)+1
   ball(i,4)=Int(Rnd*14)+1
Next



gtk_widget_show_all(win)

gtk_main()

End

Sub mymain()
   Sleep 1
   Dim As Integer i
   Cls
   For i = 1 To ballc
      Circle(ball(i,1),ball(i,2)),10,ball(i,4)
      Select Case ball(i,3)
         Case 1'up
            ball(i,2)=ball(i,2)-1
            If ball(i,2)=9 Then
               ball(i,2)=10
               ball(i,3)=2
            EndIf
         Case 2'down
            ball(i,2)=ball(i,2)+1
            If ball(i,2)=myheight-9 Then
               ball(i,2)=myheight-10
               ball(i,3)=1
            EndIf
         Case 3'left
            ball(i,1)=ball(i,1)-1
            If ball(i,1)=9 Then
               ball(i,1)=10
               ball(i,3)=4
            EndIf
         Case 4'right
            ball(i,1)=ball(i,1)+1
            If ball(i,1)=mywidth-9 Then
               ball(i,1)=mywidth-10
               ball(i,3)=3
            EndIf
         Case 5'up-left
            ball(i,2)=ball(i,2)-1
            If ball(i,2)=9 Then
               ball(i,2)=10
               ball(i,3)=7
            EndIf
            ball(i,1)=ball(i,1)-1
            If ball(i,1)=9 Then
               ball(i,1)=10
               If ball(i,3)=7 Then ball(i,3)=8 Else ball(i,3)=6
            EndIf
         Case 6'up-right
            ball(i,2)=ball(i,2)-1
            If ball(i,2)=9 Then
               ball(i,2)=10
               ball(i,3)=8
            EndIf
            ball(i,1)=ball(i,1)+1
            If ball(i,1)=mywidth-9 Then
               ball(i,1)=mywidth-10
               If ball(i,3)=8 Then ball(i,3)=7 Else ball(i,3)=5
            EndIf
         Case 7'down-left
            ball(i,2)=ball(i,2)+1
            If ball(i,2)=myheight-9 Then
               ball(i,2)=myheight-10
               ball(i,3)=5
            EndIf
            ball(i,1)=ball(i,1)-1
            If ball(i,1)=9 Then
               ball(i,1)=10
               If ball(i,3)=6 Then ball(i,3)=7 Else ball(i,3)=8
            EndIf
         Case 8'down-right
            ball(i,2)=ball(i,2)+1
            If ball(i,2)=myheight-9 Then
               ball(i,2)=myheight-10
               ball(i,3)=6
            EndIf
            ball(i,1)=ball(i,1)+1
            If ball(i,1)=mywidth-9 Then
               ball(i,1)=mywidth-10
               If ball(i,3)=6 Then ball(i,3)=5 Else ball(i,3)=7
            EndIf
      End Select
   Next
   Locate 1,1
   Print ballc
   myfbgfxtogtkimg
End Sub


Sub moreballs()
   ballc=ballc*2
   If ballc>4096 Then ballc=4096
End Sub

Sub lessballs()
   ballc=ballc/2
   If ballc<2 Then ballc=2
End Sub

Sub myfbgfxtogtkimg()
   gtk_widget_hide(myimage)
   Dim As Integer i
   Dim As UByte pixcolor,r,g,b
   Dim as ubyte ptr myfbgfx = ScreenPtr
   For i = 0 To mywidth*myheight-1
      pixcolor=*(myfbgfx+i)
      myrgbcol(pixcolor)
      *(mygetpixels+i*3)=myrgb.r
      *(mygetpixels+i*3+1)=myrgb.g
      *(mygetpixels+i*3+2)=myrgb.b
   Next
   gtk_widget_show(myimage)
End Sub

Sub myrgbcol(pc As UByte)
   Dim As UByte r,g,b
   Select Case pc
      Case 0 'black
         r=0
         g=0
         b=0
      Case 1 'blue
         r=0
         g=0
         b=255
      Case 2 'green
         r=0
         g=255
         b=0
      Case 3 'cyan
         r=0
         g=255
         b=255
      Case 4 'red
         r=255
         g=0
         b=0
      Case 5 'pink
         r=255
         g=192
         b=203
      Case 6 'yellow
         r=255
         g=255
         b=0
      Case 7 'grey
         r=128
         g=128
         b=128
      Case 8 'dark grey
         r=105
         g=105
         b=105
      Case 9 'bright blue
         r=132
         g=112
         b=255
      Case 10 'bright green
         r=127
         g=255
         b=0
      Case 11 'bright cyan
         r=105
         g=255
         b=255
      Case 12 'bright red
         r=255
         g=105
         b=105
      Case 13 'bright pink
         r=255
         g=222
         b=233
      Case 14 'bright yellow
         r=255
         g=255
         b=128
      Case 15 'white
         r=255
         g=255
         b=255
   End Select
   
   myrgb.r=r
   myrgb.g=g
   myrgb.b=b

End Sub
owen
Posts: 433
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

Re: Integrating GfxLib with Gtk

Postby owen » Aug 24, 2016 15:30

draw lines and circles example

Code: Select all

'fbcad drawarea width and height = 581 (0 to 580)
'screenres 581,581
'using widths and heights not multiples of 4 does'nt work
'use 580x580

#include "fbgfx.bi"
#DEFINE __USE_GTK3__
#include once "gtk/gtk.bi"
#LIBPATH "c:/gtk3/lib"

#Define NULL 0

Declare Function motion_notify_event Cdecl ( Byval widget As GtkWidget Ptr, Byval event As GdkEventMotion Ptr ) As Integer
Declare Function calcd(cd1 as Double,cd2 as Double,cd3 as Double,cd4 as Double,cd5 as Double,cd6 as Double) as double


Declare Sub myfbgfxtogtkimg()
Declare Sub mymain()
Declare Sub mygfxcolors()
Declare Sub myrgbcol(pc As UByte)
Declare Sub mouse_button_down()
Declare Sub mouse_button_released()
Declare Sub button_draw_line()
Declare Sub button_draw_circle()
Declare Sub drawlines
Declare Sub drawcircles



Dim Shared As GtkWidget Ptr win
Dim Shared As GtkWidget Ptr fixed
Dim As GtkWidget Ptr button1
Dim As GtkWidget Ptr button2
Dim Shared As GtkWidget Ptr myimage
Dim Shared mypixbuf as GdkPixbuf Ptr
Dim Shared mygetpixels As UByte Ptr
Dim Shared mywidth As Integer
Dim Shared myheight As Integer
Dim Shared As GtkWidget Ptr ebox
Dim Shared As Integer mygtkimage_mouse_x, mygtkimage_mouse_y
Dim Shared As BOOLEAN mousebuttondown, mousebuttonup
Dim Shared As BOOLEAN drawingline=FALSE, drawingcircle=FALSE
Dim Shared As Integer linec,circlec
Dim Shared As Double lines(100,4), circles(100,3)
Dim Shared As String drawing_entity
drawing_entity="line"

Type myclr
    r As UByte
    g As UByte
    b As UByte
End Type
Dim Shared myrgb As myclr


Dim Shared ballc As Integer


gtk_init(NULL, NULL)

win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_title(GTK_WINDOW(win), "FBgfx and GTK3image by Owen")
gtk_widget_set_size_request(win, 700, 700)


fixed = gtk_fixed_new()
gtk_container_add(GTK_CONTAINER(win), fixed)
 
button1 = gtk_button_new_with_label("Draw Lines")
gtk_widget_set_size_request(button1, 80, 35)
gtk_fixed_put(GTK_FIXED(fixed), button1, 10, 50)
g_signal_connect(G_OBJECT(button1), "clicked", G_CALLBACK (@button_draw_line), NULL)

button2 = gtk_button_new_with_label("Draw Circles")
gtk_widget_set_size_request(button2, 80, 35)
gtk_fixed_put(GTK_FIXED(fixed), button2, 10, 100)
g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK (@button_draw_circle), NULL)

g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK (@gtk_main_quit), NULL)

'for fbgfx---------
myimage = gtk_image_new_from_file("580x580-black.bmp")
mypixbuf=gtk_image_get_pixbuf(myimage)
mygetpixels=gdk_pixbuf_get_pixels (mypixbuf)
mywidth = gdk_pixbuf_get_width (mypixbuf)
myheight = gdk_pixbuf_get_height (mypixbuf)
'gtk image to display fbgfx
'gtk_fixed_put(fixed, myimage, 100, 50)
ebox = gtk_event_box_new()
gtk_container_add(GTK_CONTAINER(ebox), myimage)
gtk_fixed_put(GTK_FIXED(fixed), ebox, 100,50)

g_signal_connect(G_OBJECT(ebox), "button_press_event", G_CALLBACK(@mouse_button_down), NULL)
g_signal_connect(G_OBJECT(ebox), "button_release_event", G_CALLBACK(@mouse_button_released), NULL)
gtk_widget_set_events(G_OBJECT(ebox), GDK_POINTER_MOTION_MASK)
g_signal_connect(G_OBJECT(ebox), "motion-notify-event", G_CALLBACK(@motion_notify_event), NULL)
'gtk_widget_set_events(ebox, GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_SCROLL_MASK)




'when gtk is idle - draw the ball
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, @mymain, NULL, NULL)


'show the fb graphics screen
'ScreenRes mywidth,myheight
'hide the fb graphics screen
ScreenRes mywidth,myheight,,,fb.GFX_NULL


ballc=2
Dim Shared As Integer ball(4096,4)'x,y,direction,color
Dim As Integer i
For i = 1 To 4096
   ball(i,1)=Int(Rnd*(mywidth-11))+11
   ball(i,2)=Int(Rnd*(myheight-11))+11
   ball(i,3)=Int(Rnd*7)+1
   ball(i,4)=Int(Rnd*14)+1
Next

gtk_widget_show_all(win)

gtk_main()

End



Function motion_notify_event Cdecl ( Byval widget As GtkWidget Ptr, Byval event As GdkEventMotion Ptr ) As Integer
   mygtkimage_mouse_x = event->x
   mygtkimage_mouse_y = event->y
End Function

Function calcd(cd1 as Double,cd2 As Double,cd3 as Double,cd4 as Double,cd5 as Double,cd6 as Double) as double
   calcd = sqr((cd1-cd4)^2 + (cd2-cd5)^2 + (cd3-cd6)^2)
end function


Sub mymain()
   Sleep 1
   Dim As Integer i
   Cls
   'do not use any FB keyboard commands like input, inkey, get key
   'as it will cause a conflict with GTK
   
   'getmouse works when the FBGFX window is ACTIVE
   'but since the FBGFX window will be hidden GetMouse function will not be used
   'rather we will use GTK's mouse functions while mouse is over drawing area
   'also we will be using GTK's keyboard functions as well.
'   Dim As Integer mousex,mousey
'   GetMouse(mousex,mousey)
   'mousex and mousey will be -1 if mouse is not over the "ACTIVE" Fb graphics window
'   Print "FBGFX mouse x =";mousex, "mouse y =";mousey
   'USE GTK Keyboard and Mouse functions
   'Print "GTK mouse x =";mygtkimage_mouse_x, "mouse y =";mygtkimage_mouse_y
   If mousebuttondown=TRUE Then
      mousebuttondown=FALSE
      Select Case drawing_entity
         Case "line"
            If drawingline=FALSE Then
               drawingline=TRUE
               linec=linec+1
               lines(linec,1)=mygtkimage_mouse_x
               lines(linec,2)=mygtkimage_mouse_y
            EndIf
         Case "circle"
            If drawingcircle=FALSE Then
               drawingcircle=TRUE
               circlec=circlec+1
               circles(circlec,1)=mygtkimage_mouse_x
               circles(circlec,2)=mygtkimage_mouse_y
            EndIf            
      End Select
      'if this is the first time the mouse button is press down then begin drawing a line
   EndIf
   
   Select Case drawing_entity
      Case "line"
         If drawingline=TRUE Then Line(lines(linec,1),lines(linec,2))-(mygtkimage_mouse_x,mygtkimage_mouse_y)
      Case "circle"
         Dim r As Double
         r=calcd( circles(circlec,1) , circles(circlec,2) ,0, CDbl(mygtkimage_mouse_x), CDbl(mygtkimage_mouse_y),0)
         If drawingcircle=TRUE Then Circle( circles(circlec,1),circles(circlec,2) ),r
   End Select
   
   
   
   If mousebuttonup=TRUE Then
      mousebuttonup=FALSE
      Select Case drawing_entity
         Case "line"
            If drawingline=TRUE Then
               drawingline=FALSE
               lines(linec,3)=mygtkimage_mouse_x
               lines(linec,4)=mygtkimage_mouse_y
            EndIf         
         Case "circle"
            If drawingcircle=TRUE Then
               drawingcircle=FALSE
               Dim r As Double
               r=calcd( circles(circlec,1) , circles(circlec,2) ,0, CDbl(mygtkimage_mouse_x), CDbl(mygtkimage_mouse_y),0)
               circles(circlec,3)=r
            EndIf         
      End Select
   EndIf
   
   drawlines
   drawcircles
   myfbgfxtogtkimg
   
End Sub


Sub drawlines
   Dim As Integer i
   For i = 1 To linec
      If i=linec And drawingline=TRUE Then Exit For
      Line(lines(i,1),lines(i,2))-(lines(i,3),lines(i,4))
   Next
End Sub

Sub drawcircles
   Dim As Integer i
   For i = 1 To circlec
      If i=circlec And drawingcircle=TRUE Then Exit For
      circle(circles(i,1),circles(i,2)),circles(i,3)
   Next
End Sub



Sub button_draw_line()
   drawing_entity="line"
End Sub

Sub button_draw_circle()
   drawing_entity="circle"
End Sub


Sub mouse_button_down()
   mousebuttondown=TRUE
End Sub
Sub mouse_button_released()
   mousebuttonup=TRUE
End Sub

Sub myfbgfxtogtkimg()
   gtk_widget_hide(myimage)
   Dim As Integer i
   Dim As UByte pixcolor,r,g,b
   Dim as ubyte ptr myfbgfx = ScreenPtr
   For i = 0 To mywidth*myheight-1
      pixcolor=*(myfbgfx+i)
      myrgbcol(pixcolor)
      *(mygetpixels+i*3)=myrgb.r
      *(mygetpixels+i*3+1)=myrgb.g
      *(mygetpixels+i*3+2)=myrgb.b
   Next
   gtk_widget_show(myimage)
End Sub

Sub myrgbcol(pc As UByte)
   Dim As UByte r,g,b
   Select Case pc
      Case 0 'black
         r=0
         g=0
         b=0
      Case 1 'blue
         r=0
         g=0
         b=255
      Case 2 'green
         r=0
         g=255
         b=0
      Case 3 'cyan
         r=0
         g=255
         b=255
      Case 4 'red
         r=255
         g=0
         b=0
      Case 5 'pink
         r=255
         g=192
         b=203
      Case 6 'yellow
         r=255
         g=255
         b=0
      Case 7 'grey
         r=128
         g=128
         b=128
      Case 8 'dark grey
         r=105
         g=105
         b=105
      Case 9 'bright blue
         r=132
         g=112
         b=255
      Case 10 'bright green
         r=127
         g=255
         b=0
      Case 11 'bright cyan
         r=105
         g=255
         b=255
      Case 12 'bright red
         r=255
         g=105
         b=105
      Case 13 'bright pink
         r=255
         g=222
         b=233
      Case 14 'bright yellow
         r=255
         g=255
         b=128
      Case 15 'white
         r=255
         g=255
         b=255
   End Select
   
   myrgb.r=r
   myrgb.g=g
   myrgb.b=b

End Sub

Return to “Linux”

Who is online

Users browsing this forum: No registered users and 3 guests