From ec418a5b20377b815913a2fd37d50f0ea81c947a Mon Sep 17 00:00:00 2001
From: Mathieu L Bouchard <matju@artengine.ca>
Date: Sun, 3 Aug 2014 00:30:04 -0400
Subject: [PATCH] added dummy Qt window with three menu items

---
 pd/src/g_canvas.h  |  6 ++++
 pd/src/g_qt.cpp    | 68 ++++++++++++++++++++++++++++++++++++++++++----
 pd/src/g_qt.h      | 28 +++++++++++++++++++
 pd/src/makefile.in |  4 +--
 pd/src/s_inter.c   | 18 ++++++++++++
 5 files changed, 117 insertions(+), 7 deletions(-)

diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h
index 3f90b2eae..8e25fefec 100644
--- a/pd/src/g_canvas.h
+++ b/pd/src/g_canvas.h
@@ -770,6 +770,12 @@ EXTERN void *canvas_undo_set_font(t_canvas *x, int font);
 /* ------------------------------- */
 
 
+/* ---------- interface to Qt (libQt5) with threads -------------------- */
+
+void *qt_thread_main (void *);
+
+/* --------------------------------------------------------------------- */
+
 #if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
 }
 #endif
diff --git a/pd/src/g_qt.cpp b/pd/src/g_qt.cpp
index 72ba28b38..f73a75c38 100644
--- a/pd/src/g_qt.cpp
+++ b/pd/src/g_qt.cpp
@@ -1,17 +1,22 @@
 #include <stdio.h>
 #include <sys/time.h>
 #include <unistd.h>
+#include "m_pd.h"
+#include "g_canvas.h"
+
 #include <QtWidgets/QApplication>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QMessageBox>
+#include <QtGui/QtGui>
 #include "g_qt.h"
 
 int tv_ms_diff (timeval &a, timeval &b) {
-	return (a.tv_sec-b.tv_sec)*1000 + (a.tv_usec-b.tv_usec)/1000;
+  return (a.tv_sec-b.tv_sec)*1000 + (a.tv_usec-b.tv_usec)/1000;
 }
 
-void qt_thread_main () {
-	int argc=0; char **argv=0;
-    //QApplication app(argc,argv);
-
+static void infinite_loop () {
 	timeval t0,t1;
 	gettimeofday(&t0,0);
 	for (;;) {
@@ -20,3 +25,56 @@ void qt_thread_main () {
 		sleep(2);
 	}
 }
+
+void *qt_thread_main (void *) {
+	int argc=0; char **argv=0;
+	QApplication app(argc,argv);
+	app.setApplicationName("PureData L2ork for Qt");
+	MainWindow mainWin;
+	mainWin.show();
+	app.exec();
+	fprintf(stderr,"qt_thread_main EXITING\n");
+	return 0;
+}
+
+#define MENUITEM(MENU,ACT,TEXT,FUNC) \
+	ACT = new QAction(tr(TEXT), this); \
+	connect(ACT, SIGNAL(triggered()), this, SLOT(FUNC)); \
+	MENU->addAction(ACT);
+
+MainWindow::MainWindow () {
+	QLabel *l = new QLabel("Hello Data Flowers");
+	l->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
+	setCentralWidget(l);
+
+	fileMenu = menuBar()->addMenu(tr("&File"));
+	MENUITEM(fileMenu,quitAct,"Quit",close());
+
+	editMenu = menuBar()->addMenu(tr("&Edit"));
+	MENUITEM(editMenu,editModeAct,"&Edit mode",editMode());
+
+	menuBar()->addSeparator();
+	helpMenu = menuBar()->addMenu(tr("&Help"));
+	MENUITEM(helpMenu,aboutAct,"&About",about());
+}
+
+void MainWindow::about () {
+	QMessageBox::about(this, tr("About PureData L2ork"),
+		tr("<b>PureData</b> is an app whose purpose is to turn bits into potentially different bits."));
+}
+
+void MainWindow::editMode () {
+	QMessageBox::about(this, tr("Edit Mode"),
+		tr("To toggle edit mode, please implement this feature and recompile."));
+}
+
+bool MainWindow::askQuit () {
+	return QMessageBox::Ok == QMessageBox::warning(this, tr("Quit"),
+		tr("This will close Qt but leave Tk windows open. Proceed ?"), QMessageBox::Ok | QMessageBox::Cancel);
+}
+
+//void MainWindow::quit () {if (askQuit()) ...}
+
+void MainWindow::closeEvent(QCloseEvent *event) {
+	if (askQuit()) event->accept(); else event->ignore();
+}
diff --git a/pd/src/g_qt.h b/pd/src/g_qt.h
index 8b1378917..8833327ba 100644
--- a/pd/src/g_qt.h
+++ b/pd/src/g_qt.h
@@ -1 +1,29 @@
+// this file is for MOC/Qt stuff.
+// Do not include in C source.
+// the C interface to g_qt.c will be in g_canvas.h.
 
+#include <QtWidgets/QMainWindow>
+
+class MainWindow : public QMainWindow {
+	Q_OBJECT
+public:
+	MainWindow();
+	bool askQuit();
+	void closeEvent(QCloseEvent *event);
+
+	// list of menus
+	QMenu *fileMenu;
+	QMenu *editMenu;
+	QMenu *helpMenu;
+
+	// list of actions connecting menus/buttons to slots
+	QAction *quitAct;
+	QAction *editModeAct;
+	QAction *aboutAct;
+
+public slots:
+	// list of functions called by menus or buttons
+	//void quit ();
+	void editMode ();
+	void about ();
+};
diff --git a/pd/src/makefile.in b/pd/src/makefile.in
index 971b3c4af..047e84429 100644
--- a/pd/src/makefile.in
+++ b/pd/src/makefile.in
@@ -141,10 +141,10 @@ $(ASIOOBJ): %.o : %.cpp
 	$(CXX) $(CFLAGS) $(INCLUDE) -c -o $(OBJ_DIR)/$*.o $*.cpp
 
 ../obj/g_qt.moc.cpp : g_qt.h
-	$(MOC) $(CPPFLAGS) $(QT_INCLUDE) $< -o ../obj/$@
+	$(MOC) $(subst $(CPPFLAGS),-fno-strict-aliasing,) $(QT_INCLUDE) $< -o ../obj/$@
 
 ../obj/g_qt.moc.o : ../obj/g_qt.moc.cpp
-	$(CXX) $(CFLAGS) $(CXXFLAGS) $(QT_INCLUDE) -c ../obj/g_qt.moc.cpp -o ../obj/g_qt.moc.o
+	$(CXX) $(CFLAGS) $(CXXFLAGS) $(QT_INCLUDE) -fPIC -c ../obj/g_qt.moc.cpp -o ../obj/g_qt.moc.o
 
 ../obj/g_qt.o : g_qt.cpp
 	$(CXX) $(CFLAGS) $(CXXFLAGS) $(QT_INCLUDE) -fPIC -c g_qt.cpp -o ../obj/g_qt.o
diff --git a/pd/src/s_inter.c b/pd/src/s_inter.c
index d7c0e8e0f..15211fa50 100644
--- a/pd/src/s_inter.c
+++ b/pd/src/s_inter.c
@@ -114,6 +114,11 @@ static t_binbuf *inbinbuf;
 static t_socketreceiver *sys_socketreceiver;
 extern int sys_addhist(int phase);
 
+#ifdef QTGUI
+pthread_t sys_thread_main;
+pthread_t sys_thread_qt;
+#endif
+
 /* ----------- functions for timing, signals, priorities, etc  --------- */
 
 #ifdef MSW
@@ -889,6 +894,15 @@ static int defaultfontshit[MAXFONTS] = {
         24, 15, 28};
 #define NDEFAULTFONT (sizeof(defaultfontshit)/sizeof(*defaultfontshit))
 
+
+#ifdef QTGUI
+void sys_start_qt () {
+	sys_thread_main = pthread_self();
+	int r = pthread_create(&sys_thread_qt,0,qt_thread_main,0);
+	if (r) fprintf(stderr,"pthread_create: %s",strerror(r));
+}
+#endif
+
 int sys_startgui(const char *guidir)
 {
     pid_t childpid;
@@ -1166,6 +1180,10 @@ int sys_startgui(const char *guidir)
 
 #endif /* MSW */
     }
+    
+#ifdef QTGUI
+	if (sys_qtcanvas) sys_start_qt();
+#endif
 
 #if defined(__linux__) || defined(IRIX)
         /* now that we've spun off the child process we can promote
-- 
GitLab