[Gambas-devel] Windows stuff

Brandon Bergren bdragon at ...185...
Fri Mar 11 07:27:22 CET 2005



On Fri, 11 Mar 2005, Daniel Campos wrote:

> OK, Brandom, good job! I hope you'll publish a tutorial soon about this...
>
>> 
>> 
>> The only stuff currently disabled is:
>> 
>> Plugin stuff -- There isn't glue code in gtk for windows. Should be easy, 
>> probabaly possible to make a single file glue to drop in that doesn't 
>> require a gtk recompile. Really, since windows isn't picky about security 
>> like X, making most of the Plugin/Socket stuff nullop should just work(tm)
>
>
> As I said in aprevious message, I made a program in VB that used a foreign 
> window, however I have got not the sources as I was not allowed to copy them 
> in my old company. But it is possible to emulate that function in Win$.
> However... what key word should I use to disable this in the Win$ 
> compilation? ( #ifndef CYGWIN or #ifndef WINDOWS...?)

Well, I started using OS_WINDOWS for native windows stuff.
Benoit: do you think that is a good define for a non-cygwin windows native 
compile?

Here's a really old patch someone made in 2001 that kinda implements 
plugin/socket.
http://bugzilla.gnome.org/attachment.cgi?id=5917&action=view



>
>> 
>> TrayIcon -- Platform dependent crap. Daniel: Would you accept windows 
>> patches? :)
>
>
> Yes, of course I accept patches, but as I said in the previous point I just 
> need to know the macro that I need to
> disable it in the Win version (or to include the Systray code for windows). 
> However, note that I do not accept the
> "crap" adjective for that code, it is freedesktop compliant.

oops, sorry about that. I type like I speak.

I forget that X is quite platform agnostic, 
but I have the luck to use Windows and BeOS machines. :(

Too bad Windows isn't freedesktop.org compliant! ;)
(hmm, now where would I send patches to fix that....)

>
>
>> 
>> 
>> CWatcher -- I had to remove the filewatcher hook. Watching file descriptors 
>> on Windows is DIFFERENT. Daniel: Why do you need to override the default 
>> watch hook?
>
> Talking properly, watching file descriptors in Windows is not possible, it is 
> just an API emulation that Win$ people added to their API because they 
> realized it was important after they released the first version :-))

You nailed that one right on the head.

> Well, 
> the GTK+ component uses the MAIN hook, so I have to watch the file 
> descriptors myself, Gambas can not do it, look at the QT component, it has 
> the same "problem". However, I'm using the same stuff that Benoît uses in 
> the gambas watch code to watch the file descriptors, so I do not understand 
> why the gambas watching code works and not the code included in the gb.gtk 
> component.

Because his code is still compiled against cygwin, and I'm trying to get 
yours to not depend on it.

Really, I don't see a way to hook WATCH right now on Windows. It's really 
hard to figure out the kernel file object from a descriptor. (impossible?) 
The other two ways of keeping track of a file on Windows would work better...
(by other two ways, I mean passing HANDLEs and CFILEs.)

That would break the ABI interface, though... :(

I might see if I can tweak gbx to use CreateFile and pass the handle 
across the interface instead of a FD.

"Windows doesn't have design flaws. Windows IS a design flaw." -- me

> The DNS async code can not work if you remove the watching code, 
> sockets can not work, too...

Well, the DNS async code doesn't work on Windows properly, anyway.
Too bad the whole OS wasn't designed around Winsock2.

>
>
>> 
>> and the event loop doesn't have a sleep in it. (but it still doesn't take a 
>> bunch of CPU time... I don't know why...)
>> 
And then I notice that I actually put in Sleep(10); instead.  Heh.


> Mmmhh... another #ifdef that I should include.
>


Here's some other ifdefs:

#ifndef OS_WINDOWS
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#else
#include <gdk/gdkwin32.h>
#endif

and

long gControl::handle()
{
#ifndef OS_WINDOWS
 	return (long)GDK_WINDOW_XID(border->window);
#else
     return (long)GDK_WINDOW_HWND(border->window);
#endif
}


I have never used GTK before. First time I actually read any sort of 
documentation on it was today. I'm used to Fox.



>> I tested the Notepad example so far. It crashes when you save, but the rest 
>> seems to work OK.
>> 
>> Here's the console output, if anyone can tell me what is happening here, 
>> I'd like to know.
>> 
>> DataObject Shell IDList Array Preferred DropEffect Shell Object Offsets 
>> FileName FileNameW Ole Private Data
>> (gbx2): GLib-CRITICAL **: g_convert: assertion `str != NULL' failed
>
> ? I don't know yet, I have to investigate it.
>

Well, could be because of my changes.  I listed them at the end. If I did 
anything stupid to your code (most likely), shout.

The line above seems to be nonfatal. Everything seems to print that one.


>> FNotepad.?.0: #43: Access forbidden
>> WARNING: circular references detected
>> FNotepad (1)

I think this is where it's actually dumping.


>> WARNING: CCONTAINER_width not yet implemented
>
>
>> WARNING: CCONTAINER_height not yet implemented
>> WARNING: gButton::setCancel() not yet implemented

And I think these are printed later because of my stupid buffered console.

>
>
> I have to write the code for CCONTAINER_width, height and setCancel(), this 
> is normal
>
Yeah. I saw those warnings in the X11 version too.


>> 
>> Of course, it's probabaly having something to do with one of the bits that 
>> doesn't work properly.
>> 
>> I also had to stub two unimplemented functions (Daniel, why isn't this a 
>> compile error for you?)
>
> Linux compiler allows to compile it, and then, if the function is called, the 
> program stops with an error (undefined symbol...) What are these two 
> functions?

void gListBox::setIndex(long vl)
void gListBox::setItemText(long ind,char *txt)

Do you get a warning? I noticed you have a few instances of missing 
newline at end of file... I could've sworn linux warns about that too...

how bout using "make 2>warnings.txt" so you can notice these?


>
>
>> 
>> 
>> 
>> Well, that's about it, screenshots will follow soon.
>
> Cool
>
>> 
>> 
>> --Brandon
>
>
> Regards,
>
> D. Campos
>

Here's a diff, along with commentary.


diff -u -x '*.o' ./CFont.h ../../CFont.h
--- ./CFont.h	2005-01-20 09:09:55.000000000 -0600
+++ ../../CFont.h	2005-03-10 18:26:00.085782400 -0600
@@ -54,4 +54,4 @@
  }  CFONT;


-#endif
\ No newline at end of file
+#endif


I just added a newline at end of file here.



diff -u -x '*.o' ./CTrayIcon.h ../../CTrayIcon.h
--- ./CTrayIcon.h	2005-03-04 13:18:20.000000000 -0600
+++ ../../CTrayIcon.h	2005-03-10 18:55:52.000000000 -0600
@@ -42,7 +42,7 @@
  typedef  struct
  {
      GB_BASE ob;
-	gTrayIcon *icon;
+//	gTrayIcon *icon;

  }  CTRAYICON;


Here's me commenting out part of TrayIcon.


diff -u -x '*.o' ./gcontrol.cpp ../../gcontrol.cpp
--- ./gcontrol.cpp	2005-03-05 04:21:59.000000000 -0600
+++ ../../gcontrol.cpp	2005-03-10 18:54:38.000000000 -0600
@@ -28,7 +28,11 @@
  #include <stdio.h>

  #include <gtk/gtk.h>
+#ifndef OS_WINDOWS
  #include <gdk/gdkx.h>
+#else
+#include <gdk/gdkwin32.h>
+#endif
  #include <stdlib.h>
  #include <string.h>
  #include "widgets.h"
@@ -159,17 +163,17 @@

  gboolean gPlugin_OnUnplug(GtkSocket *socket,gPlugin *data)
  {
-	if (data->onUnplug) data->onUnplug(data);
-	return true;
+//if (data->onUnplug) data->onUnplug(data);
+//	return true;
  }

  void gPlugin_OnPlug(GtkSocket *socket,gPlugin *data)
  {
-	if (data->onPlug) data->onPlug(data);
+//	if (data->onPlug) data->onPlug(data);
  }

  gPlugin::gPlugin(gControl *parent) : gControl(parent)
-{
+{/*
  	g_typ=Type_gPlugin;
  	border=gtk_event_box_new();
  	widget=gtk_socket_new();
@@ -180,14 +184,15 @@
  	onUnplug=NULL;
  	g_signal_connect(G_OBJECT(widget),"plug-removed",G_CALLBACK(gPlugin_OnUnplug),(gpointer)this);
  	g_signal_connect(G_OBJECT(widget),"plug-added",G_CALLBACK(gPlugin_OnPlug),(gpointer)this);
- 
+*/
  }

  void gPlugin::plug(long id)
  {
-	gtk_socket_add_id(GTK_SOCKET(widget),(GdkNativeWindow)id);
+	//gtk_socket_add_id(GTK_SOCKET(widget),(GdkNativeWindow)id);
  }

+
  void gControl::destroy()
  {
  	gtk_widget_destroy(border);
@@ -732,7 +737,11 @@
  }
  long gControl::handle()
  {
+#ifndef OS_WINDOWS
  	return (long)GDK_WINDOW_XID(border->window);
+#else
+    return (long)GDK_WINDOW_HWND(border->window);
+#endif
  }
  /*****************************************************************

@@ -860,7 +869,7 @@
  		entry[1].flags=0;
  		entry[1].info=0;

-		gtk_drag_dest_set(border,(GtkDestDefaults)0,0, \ 
+		gtk_drag_dest_set(border,(GtkDestDefaults)0,0, \
  							0, \
  							(GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK));
  		//gtk_drag_dest_set(w,(GtkDestDefaults)0,0, \


Yeah, I did a lot of stuff here.
The last hunk is interesting. You have a space after the \ at the end of 
the line.  My compiler warned me about that....




diff -u -x '*.o' ./glistbox.cpp ../../glistbox.cpp
--- ./glistbox.cpp	2005-03-05 03:22:53.000000000 -0600
+++ ../../glistbox.cpp	2005-03-10 18:29:56.000000000 -0600
@@ -423,4 +423,12 @@
  	gStoreList_Clear(STORE_LIST);
  }

+void gListBox::setIndex(long vl)
+{
+    stub("gListBox::setIndex"); 
+}

+void gListBox::setItemText(long ind,char *txt)
+{
+     stub("gListBox::setItemText");
+}


And here's the missing stubs.



diff -u -x '*.o' ./gmainwindow.cpp ../../gmainwindow.cpp
--- ./gmainwindow.cpp	2005-03-06 15:10:30.000000000 -0600
+++ ../../gmainwindow.cpp	2005-03-10 18:50:30.000000000 -0600
@@ -108,7 +108,8 @@
  	windows[nwindows-1]=this;

  	if (plug)
-		border=gtk_plug_new(0);
+	    stub("mainwindow plugin");
+//		border=gtk_plug_new(0);
  	else
  		border=gtk_window_new(GTK_WINDOW_TOPLEVEL);

@@ -490,7 +491,9 @@

  void gApplication::iteration()
  {
+#ifndef OS_WINDOWS
  	struct timespec mywait;
+#endif

  	if (gtk_events_pending ())
  	{
@@ -498,9 +501,13 @@
  	}
  	else
  	{
+#ifndef OS_WINDOWS
  		mywait.tv_sec=0;
  		mywait.tv_nsec=100000;
  		nanosleep(&mywait,NULL);
+#else
+      Sleep(10);
+#endif
  	}
  }



And here's me hacking around the lack of nanosleep and struct timespec.



diff -u -x '*.o' ./main.cpp ../../main.cpp
--- ./main.cpp	2005-03-07 09:26:52.000000000 -0600
+++ ../../main.cpp	2005-03-10 19:01:58.000000000 -0600
@@ -85,10 +85,10 @@
  extern "C"
  {

-	GB_INTERFACE GB;
+__declspec(dllexport)	GB_INTERFACE GB;


-	GB_DESC *GB_CLASSES[] =
+__declspec(dllexport)	GB_DESC *GB_CLASSES[] =
  	{
  		CTimerDesc,
  		CDesktopDesc,
@@ -168,22 +168,22 @@
  		NULL
  	};

-	int GB_INIT(void)
+__declspec(dllexport)	int GB_INIT(void)
  	{
-		CWatcher::Init();
+//		CWatcher::Init();
  		gMessage::setTitle(GB.Application.Name());
  		GB.Hook(GB_HOOK_QUIT, (void *)my_quit);
  		GB.Hook(GB_HOOK_MAIN, (void *)my_main);
  		GB.Hook(GB_HOOK_WAIT, (void *)my_wait);
  		GB.Hook(GB_HOOK_LOOP, (void *)my_loop);
-		GB.Hook(GB_HOOK_WATCH,(void *)my_watch);
+	//	GB.Hook(GB_HOOK_WATCH,(void *)my_watch);
  		GB.Hook(GB_HOOK_POST,(void*)my_post);
  		return FALSE;
  	}

-	void GB_EXIT()
+__declspec(dllexport)	void GB_EXIT()
  	{
-		CWatcher::Clear();
+	//	CWatcher::Clear();
  		gMessage::setTitle(NULL);
  		gDialog::setPath(NULL);
  		gDialog::setFilter(NULL,0);
@@ -234,13 +234,13 @@

  static void my_watch(int fd, int type, void *callback, long param)
  {
-	CWatcher::Add(fd,type,callback,param);
+//	CWatcher::Add(fd,type,callback,param);
  }

  void do_iteration(void)
  {
  	if (post_Check) { post_Check=false; GB.CheckPost(); }
-	CWatcher::Perform();
+//	CWatcher::Perform();
  	gApplication::iteration();
  }


I had to manually export the interface symbols, because I was too lazy to 
write a .def file for the DLL.




diff -u -x '*.o' ./widgets.h ../../widgets.h
--- ./widgets.h	2005-03-07 09:59:14.000000000 -0600
+++ ../../widgets.h	2005-03-10 18:53:58.038560000 -0600
@@ -25,9 +25,13 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

  ***************************************************************************/
-
+#ifndef OS_WINDOWS
  #include <gtk/gtk.h>
  #include <gdk/gdkx.h>
+#else
+#include <gtk/gtk.h>
+#include <gdk/gdkwin32.h>
+#endif
  #ifndef __widgets_h
  #define __widgets_h

@@ -505,6 +509,7 @@
  	void connectParent();
  };

+/*
  class gTrayIcon
  {
  public:
@@ -532,13 +537,17 @@
  	GtkWidget *img;
  	GtkTooltips *tip;

+#ifndef OS_WINDOWS
  	Screen *xscreen;
  	Display *xdisplay;
+
  	Atom selection_atom;
  	Atom manager_atom;
  	Atom system_tray_opcode_atom;
  	Window manager_window;
+#endif
  };
+*/

  class gPlugin : public gControl
  {
@@ -925,6 +934,15 @@
  	gSlider(gControl *parent);

  //"Properties"
+
+#ifdef OS_WINDOWS
+
+ #undef max
+ #undef min
+
+#endif
+
+
  	long max();
  	long min();
  	bool tracking();


The last hunk is of interest.
min and max are macros here. (stupid namespace pollution...)

Really, having min() and max() member functions is kinda asking for 
trouble.


More information about the Devel mailing list