aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2005-05-27 06:36:43 +0000
committerChristian Grothoff <christian@grothoff.org>2005-05-27 06:36:43 +0000
commita2204bd122748814c5782decd322e46e67d5a4ac (patch)
tree7ca68b8710e75cb5b99f309477f6f38e28fee322
parente89c480c5d9985674535fe6ee1e196c6738643cd (diff)
downloadgnunet-gtk-a2204bd122748814c5782decd322e46e67d5a4ac.tar.gz
gnunet-gtk-a2204bd122748814c5782decd322e46e67d5a4ac.zip
update
-rw-r--r--gnunet-gtk.glade310
-rw-r--r--src/Makefile.am13
-rw-r--r--src/about.c125
-rw-r--r--src/daemon.c315
-rw-r--r--src/daemon.h33
-rw-r--r--src/fs.c54
-rw-r--r--src/fs.h39
-rw-r--r--src/gtk26about.c1846
-rw-r--r--src/gtk26about.h117
-rw-r--r--src/helper.c498
-rw-r--r--src/helper.h139
-rw-r--r--src/main.c47
-rw-r--r--src/main.h35
-rw-r--r--src/platform.h175
-rw-r--r--src/plibc.h565
-rw-r--r--todo17
16 files changed, 4193 insertions, 135 deletions
diff --git a/gnunet-gtk.glade b/gnunet-gtk.glade
index f2ab15ba..ec7193bc 100644
--- a/gnunet-gtk.glade
+++ b/gnunet-gtk.glade
@@ -52,7 +52,7 @@
52 <property name="visible">True</property> 52 <property name="visible">True</property>
53 <property name="label">gtk-about</property> 53 <property name="label">gtk-about</property>
54 <property name="use_stock">True</property> 54 <property name="use_stock">True</property>
55 <signal name="activate" handler="on_about_activate"/> 55 <signal name="activate" handler="on_about_clicked"/>
56 </widget> 56 </widget>
57 </child> 57 </child>
58 </widget> 58 </widget>
@@ -78,19 +78,60 @@
78 <property name="enable_popup">False</property> 78 <property name="enable_popup">False</property>
79 79
80 <child> 80 <child>
81 <widget class="GtkLabel" id="splashScreen"> 81 <widget class="GtkScrolledWindow" id="scrolledwindow19">
82 <property name="visible">True</property> 82 <property name="visible">True</property>
83 <property name="label" translatable="yes">Welcome to GNUnet 83 <property name="can_focus">True</property>
84</property> 84 <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
85 <property name="use_underline">False</property> 85 <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
86 <property name="use_markup">True</property> 86 <property name="shadow_type">GTK_SHADOW_NONE</property>
87 <property name="justify">GTK_JUSTIFY_LEFT</property> 87 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
88 <property name="wrap">True</property> 88
89 <property name="selectable">False</property> 89 <child>
90 <property name="xalign">0.5</property> 90 <widget class="GtkViewport" id="viewport6">
91 <property name="yalign">0.5</property> 91 <property name="visible">True</property>
92 <property name="xpad">0</property> 92 <property name="shadow_type">GTK_SHADOW_IN</property>
93 <property name="ypad">0</property> 93
94 <child>
95 <widget class="GtkLabel" id="label75">
96 <property name="visible">True</property>
97 <property name="label" translatable="yes">&lt;span size=&quot;x-large&quot;&gt;Welcome to gnunet-gtk 0.7.0&lt;/span&gt;
98
99gnunet-gtk is the GTK+ user interface for GNUnet. It is intended to eventually provide a universal, pluggable interface for all GNUnet services.
100
101This is an alpha release. Many features are not working and others are missing. The GNUnet homepage offers information about new versions of gnunet-gtk.
102
103&lt;span size=&quot;x-large&quot;&gt;Important changes (compared to gnunet-gtk 0.6.6):&lt;/span&gt;
104
105The redesign of the GNUnet core has also affected gnunet-gtk. The new codebase is based on glade, which should make it easier to customize and extend gnunet-gtk.
106
107The new codebase is mostly a collection of GTK+ signal handlers that trigger the appropriate actions on GNUnet's FSUI and ECRS libraries.
108
109The code is still far from complete, missing features include:
110* support for starting and stopping gnunetd
111* support for file sharing (insert, search, download, pseudonyms, namespaces, directories, collections)
112* support for statistics (raw, graphical)
113* support for chat
114
115We hope that you will enjoy gnunet-gtk (especially once it is ready).
116
117
118Thank you,
119
120
121 The GNUnet Team</property>
122 <property name="use_underline">False</property>
123 <property name="use_markup">True</property>
124 <property name="justify">GTK_JUSTIFY_LEFT</property>
125 <property name="wrap">True</property>
126 <property name="selectable">False</property>
127 <property name="xalign">0.5</property>
128 <property name="yalign">0.5</property>
129 <property name="xpad">0</property>
130 <property name="ypad">0</property>
131 </widget>
132 </child>
133 </widget>
134 </child>
94 </widget> 135 </widget>
95 <packing> 136 <packing>
96 <property name="tab_expand">False</property> 137 <property name="tab_expand">False</property>
@@ -166,12 +207,12 @@
166 <property name="spacing">0</property> 207 <property name="spacing">0</property>
167 208
168 <child> 209 <child>
169 <widget class="GtkButton" id="startGnunetdButton"> 210 <widget class="GtkButton" id="startDaemon">
170 <property name="visible">True</property> 211 <property name="visible">True</property>
171 <property name="can_focus">True</property> 212 <property name="can_focus">True</property>
172 <property name="relief">GTK_RELIEF_NORMAL</property> 213 <property name="relief">GTK_RELIEF_NORMAL</property>
173 <property name="focus_on_click">True</property> 214 <property name="focus_on_click">True</property>
174 <signal name="clicked" handler="on_startGnunetdButton_clicked" last_modification_time="Mon, 23 May 2005 19:05:11 GMT"/> 215 <signal name="clicked" handler="on_startDaemon_clicked" last_modification_time="Mon, 23 May 2005 19:05:11 GMT"/>
175 216
176 <child> 217 <child>
177 <widget class="GtkAlignment" id="alignment1"> 218 <widget class="GtkAlignment" id="alignment1">
@@ -211,7 +252,7 @@
211 <child> 252 <child>
212 <widget class="GtkLabel" id="startButton"> 253 <widget class="GtkLabel" id="startButton">
213 <property name="visible">True</property> 254 <property name="visible">True</property>
214 <property name="label" translatable="yes">_start gnunetd</property> 255 <property name="label" translatable="yes">start gnunetd</property>
215 <property name="use_underline">True</property> 256 <property name="use_underline">True</property>
216 <property name="use_markup">False</property> 257 <property name="use_markup">False</property>
217 <property name="justify">GTK_JUSTIFY_RIGHT</property> 258 <property name="justify">GTK_JUSTIFY_RIGHT</property>
@@ -287,7 +328,7 @@
287 <child> 328 <child>
288 <widget class="GtkLabel" id="label64"> 329 <widget class="GtkLabel" id="label64">
289 <property name="visible">True</property> 330 <property name="visible">True</property>
290 <property name="label" translatable="yes">s_top gnunetd</property> 331 <property name="label" translatable="yes">stop gnunetd</property>
291 <property name="use_underline">True</property> 332 <property name="use_underline">True</property>
292 <property name="use_markup">False</property> 333 <property name="use_markup">False</property>
293 <property name="justify">GTK_JUSTIFY_LEFT</property> 334 <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -317,7 +358,7 @@
317 </child> 358 </child>
318 359
319 <child> 360 <child>
320 <widget class="GtkImage" id="statusPixmap"> 361 <widget class="GtkImage" id="statusPixmapNo">
321 <property name="visible">True</property> 362 <property name="visible">True</property>
322 <property name="stock">gtk-no</property> 363 <property name="stock">gtk-no</property>
323 <property name="icon_size">4</property> 364 <property name="icon_size">4</property>
@@ -327,7 +368,29 @@
327 <property name="ypad">0</property> 368 <property name="ypad">0</property>
328 <accessibility> 369 <accessibility>
329 <atkproperty name="AtkObject::accessible_name" translatable="yes">status</atkproperty> 370 <atkproperty name="AtkObject::accessible_name" translatable="yes">status</atkproperty>
330 <atkproperty name="AtkObject::accessible_description" translatable="yes">gnunetd status</atkproperty> 371 <atkproperty name="AtkObject::accessible_description" translatable="yes">gnunetd status: not running</atkproperty>
372 </accessibility>
373 </widget>
374 <packing>
375 <property name="padding">0</property>
376 <property name="expand">False</property>
377 <property name="fill">False</property>
378 </packing>
379 </child>
380
381 <child>
382 <widget class="GtkImage" id="statusPixmapYes">
383 <property agent="glademm" name="cxx_visibility">public</property>
384 <property name="visible">True</property>
385 <property name="stock">gtk-yes</property>
386 <property name="icon_size">4</property>
387 <property name="xalign">0.5</property>
388 <property name="yalign">0.5</property>
389 <property name="xpad">0</property>
390 <property name="ypad">0</property>
391 <accessibility>
392 <atkproperty name="AtkObject::accessible_name" translatable="yes">status</atkproperty>
393 <atkproperty name="AtkObject::accessible_description" translatable="yes">gnunetd status: running</atkproperty>
331 </accessibility> 394 </accessibility>
332 </widget> 395 </widget>
333 <packing> 396 <packing>
@@ -432,6 +495,7 @@
432 495
433 <child> 496 <child>
434 <widget class="GtkTreeView" id="clist2"> 497 <widget class="GtkTreeView" id="clist2">
498 <property agent="glademm" name="cxx_visibility">public</property>
435 <property name="visible">True</property> 499 <property name="visible">True</property>
436 <property name="can_focus">True</property> 500 <property name="can_focus">True</property>
437 <property name="headers_visible">True</property> 501 <property name="headers_visible">True</property>
@@ -535,6 +599,7 @@
535 599
536 <child> 600 <child>
537 <widget class="GtkTreeView" id="clist7"> 601 <widget class="GtkTreeView" id="clist7">
602 <property agent="glademm" name="cxx_visibility">public</property>
538 <property name="visible">True</property> 603 <property name="visible">True</property>
539 <property name="can_focus">True</property> 604 <property name="can_focus">True</property>
540 <property name="headers_visible">True</property> 605 <property name="headers_visible">True</property>
@@ -589,6 +654,7 @@
589 654
590 <child> 655 <child>
591 <widget class="GtkTreeView" id="clist5"> 656 <widget class="GtkTreeView" id="clist5">
657 <property agent="glademm" name="cxx_visibility">public</property>
592 <property name="visible">True</property> 658 <property name="visible">True</property>
593 <property name="can_focus">True</property> 659 <property name="can_focus">True</property>
594 <property name="headers_visible">True</property> 660 <property name="headers_visible">True</property>
@@ -643,6 +709,7 @@
643 709
644 <child> 710 <child>
645 <widget class="GtkTreeView" id="clist6"> 711 <widget class="GtkTreeView" id="clist6">
712 <property agent="glademm" name="cxx_visibility">public</property>
646 <property name="visible">True</property> 713 <property name="visible">True</property>
647 <property name="can_focus">True</property> 714 <property name="can_focus">True</property>
648 <property name="headers_visible">True</property> 715 <property name="headers_visible">True</property>
@@ -712,7 +779,8 @@
712 <property name="spacing">0</property> 779 <property name="spacing">0</property>
713 780
714 <child> 781 <child>
715 <widget class="GtkNotebook" id="notebook6"> 782 <widget class="GtkNotebook" id="downloadNotebook">
783 <property agent="glademm" name="cxx_visibility">public</property>
716 <property name="can_focus">True</property> 784 <property name="can_focus">True</property>
717 <property name="show_tabs">True</property> 785 <property name="show_tabs">True</property>
718 <property name="show_border">True</property> 786 <property name="show_border">True</property>
@@ -783,7 +851,8 @@
783 </accessibility> 851 </accessibility>
784 852
785 <child internal-child="entry"> 853 <child internal-child="entry">
786 <widget class="GtkEntry" id="combo-entry2"> 854 <widget class="GtkEntry" id="searchKeywordGtkEntry">
855 <property agent="glademm" name="cxx_visibility">public</property>
787 <property name="visible">True</property> 856 <property name="visible">True</property>
788 <property name="can_focus">True</property> 857 <property name="can_focus">True</property>
789 <property name="editable">True</property> 858 <property name="editable">True</property>
@@ -931,24 +1000,9 @@
931 </child> 1000 </child>
932 1001
933 <child> 1002 <child>
934 <widget class="GtkOptionMenu" id="optionmenu1"> 1003 <widget class="GtkComboBoxEntry" id="searchNamespaceComboBoxEntry">
1004 <property agent="glademm" name="cxx_visibility">public</property>
935 <property name="visible">True</property> 1005 <property name="visible">True</property>
936 <property name="can_focus">True</property>
937 <property name="history">0</property>
938
939 <child internal-child="menu">
940 <widget class="GtkMenu" id="convertwidget16">
941 <property name="visible">True</property>
942
943 <child>
944 <widget class="GtkMenuItem" id="convertwidget17">
945 <property name="visible">True</property>
946 <property name="label" translatable="yes">global (everywhere)</property>
947 <property name="use_underline">True</property>
948 </widget>
949 </child>
950 </widget>
951 </child>
952 </widget> 1006 </widget>
953 <packing> 1007 <packing>
954 <property name="padding">0</property> 1008 <property name="padding">0</property>
@@ -1025,6 +1079,7 @@
1025 1079
1026 <child> 1080 <child>
1027 <widget class="GtkRadioButton" id="indexbutton"> 1081 <widget class="GtkRadioButton" id="indexbutton">
1082 <property agent="glademm" name="cxx_visibility">public</property>
1028 <property name="visible">True</property> 1083 <property name="visible">True</property>
1029 <property name="can_focus">True</property> 1084 <property name="can_focus">True</property>
1030 <property name="label" translatable="yes">index</property> 1085 <property name="label" translatable="yes">index</property>
@@ -1044,6 +1099,7 @@
1044 1099
1045 <child> 1100 <child>
1046 <widget class="GtkRadioButton" id="insertButton"> 1101 <widget class="GtkRadioButton" id="insertButton">
1102 <property agent="glademm" name="cxx_visibility">public</property>
1047 <property name="visible">True</property> 1103 <property name="visible">True</property>
1048 <property name="can_focus">True</property> 1104 <property name="can_focus">True</property>
1049 <property name="label" translatable="yes">insert</property> 1105 <property name="label" translatable="yes">insert</property>
@@ -1099,6 +1155,7 @@
1099 1155
1100 <child> 1156 <child>
1101 <widget class="GtkRadioButton" id="radiobutton2"> 1157 <widget class="GtkRadioButton" id="radiobutton2">
1158 <property agent="glademm" name="cxx_visibility">public</property>
1102 <property name="visible">True</property> 1159 <property name="visible">True</property>
1103 <property name="can_focus">True</property> 1160 <property name="can_focus">True</property>
1104 <property name="label" translatable="yes">file only</property> 1161 <property name="label" translatable="yes">file only</property>
@@ -1118,6 +1175,7 @@
1118 1175
1119 <child> 1176 <child>
1120 <widget class="GtkRadioButton" id="radiobutton3"> 1177 <widget class="GtkRadioButton" id="radiobutton3">
1178 <property agent="glademm" name="cxx_visibility">public</property>
1121 <property name="visible">True</property> 1179 <property name="visible">True</property>
1122 <property name="can_focus">True</property> 1180 <property name="can_focus">True</property>
1123 <property name="label" translatable="yes">recursive (for entire directories)</property> 1181 <property name="label" translatable="yes">recursive (for entire directories)</property>
@@ -1182,6 +1240,7 @@
1182 1240
1183 <child internal-child="entry"> 1241 <child internal-child="entry">
1184 <widget class="GtkEntry" id="combo-entry1"> 1242 <widget class="GtkEntry" id="combo-entry1">
1243 <property agent="glademm" name="cxx_visibility">public</property>
1185 <property name="visible">True</property> 1244 <property name="visible">True</property>
1186 <property name="can_focus">True</property> 1245 <property name="can_focus">True</property>
1187 <property name="editable">True</property> 1246 <property name="editable">True</property>
@@ -1236,7 +1295,7 @@
1236 <property name="can_focus">True</property> 1295 <property name="can_focus">True</property>
1237 <property name="relief">GTK_RELIEF_NORMAL</property> 1296 <property name="relief">GTK_RELIEF_NORMAL</property>
1238 <property name="focus_on_click">True</property> 1297 <property name="focus_on_click">True</property>
1239 <signal name="activate" handler="on_mainFileSharingInsertBrowseButton_activate" object="fsinsertfilenamecombo" last_modification_time="Mon, 23 May 2005 17:09:36 GMT"/> 1298 <signal name="clicked" handler="on_mainFileSharingInsertBrowseButton_clicked" object="fsinsertfilenamecombo" last_modification_time="Mon, 23 May 2005 17:09:36 GMT"/>
1240 1299
1241 <child> 1300 <child>
1242 <widget class="GtkAlignment" id="alignment7"> 1301 <widget class="GtkAlignment" id="alignment7">
@@ -1437,7 +1496,7 @@
1437 <property name="visible">True</property> 1496 <property name="visible">True</property>
1438 <property name="label" translatable="yes">_Namespace</property> 1497 <property name="label" translatable="yes">_Namespace</property>
1439 <property name="use_underline">True</property> 1498 <property name="use_underline">True</property>
1440 <signal name="activate_item" handler="on_create_namespace_activate" last_modification_time="Mon, 23 May 2005 19:13:47 GMT"/> 1499 <signal name="activate_item" handler="on_create_namespace_clicked" last_modification_time="Mon, 23 May 2005 19:13:47 GMT"/>
1441 </widget> 1500 </widget>
1442 </child> 1501 </child>
1443 1502
@@ -1446,7 +1505,7 @@
1446 <property name="visible">True</property> 1505 <property name="visible">True</property>
1447 <property name="label" translatable="yes">_Directory</property> 1506 <property name="label" translatable="yes">_Directory</property>
1448 <property name="use_underline">True</property> 1507 <property name="use_underline">True</property>
1449 <signal name="activate_item" handler="on_create_directory_activate" last_modification_time="Mon, 23 May 2005 19:13:40 GMT"/> 1508 <signal name="activate_item" handler="on_create_directory_clicked" last_modification_time="Mon, 23 May 2005 19:13:40 GMT"/>
1450 </widget> 1509 </widget>
1451 </child> 1510 </child>
1452 1511
@@ -1455,7 +1514,7 @@
1455 <property name="visible">True</property> 1514 <property name="visible">True</property>
1456 <property name="label" translatable="yes">_Collection</property> 1515 <property name="label" translatable="yes">_Collection</property>
1457 <property name="use_underline">True</property> 1516 <property name="use_underline">True</property>
1458 <signal name="activate_item" handler="on_create_collection_activate" last_modification_time="Mon, 23 May 2005 19:13:32 GMT"/> 1517 <signal name="activate_item" handler="on_create_collection_clicked" last_modification_time="Mon, 23 May 2005 19:13:32 GMT"/>
1459 </widget> 1518 </widget>
1460 </child> 1519 </child>
1461 1520
@@ -1464,7 +1523,7 @@
1464 <property name="visible">True</property> 1523 <property name="visible">True</property>
1465 <property name="label" translatable="yes">_Advertisement</property> 1524 <property name="label" translatable="yes">_Advertisement</property>
1466 <property name="use_underline">True</property> 1525 <property name="use_underline">True</property>
1467 <signal name="activate_item" handler="on_create_advertisement_activate" last_modification_time="Mon, 23 May 2005 19:13:53 GMT"/> 1526 <signal name="activate_item" handler="on_create_advertisement_clicked" last_modification_time="Mon, 23 May 2005 19:13:53 GMT"/>
1468 </widget> 1527 </widget>
1469 </child> 1528 </child>
1470 </widget> 1529 </widget>
@@ -1488,7 +1547,7 @@
1488 <property name="tooltip" translatable="yes">Will prevent future insertions into the namespace (will not delete content in the namespace)</property> 1547 <property name="tooltip" translatable="yes">Will prevent future insertions into the namespace (will not delete content in the namespace)</property>
1489 <property name="label" translatable="yes">_Namespace</property> 1548 <property name="label" translatable="yes">_Namespace</property>
1490 <property name="use_underline">True</property> 1549 <property name="use_underline">True</property>
1491 <signal name="activate_item" handler="on_namespace2_activate" last_modification_time="Mon, 23 May 2005 19:14:04 GMT"/> 1550 <signal name="activate_item" handler="on_namespace2_clicked" last_modification_time="Mon, 23 May 2005 19:14:04 GMT"/>
1492 </widget> 1551 </widget>
1493 </child> 1552 </child>
1494 1553
@@ -1498,7 +1557,7 @@
1498 <property name="tooltip" translatable="yes">end collection (will not delete content already in the collection)</property> 1557 <property name="tooltip" translatable="yes">end collection (will not delete content already in the collection)</property>
1499 <property name="label" translatable="yes">_Collection</property> 1558 <property name="label" translatable="yes">_Collection</property>
1500 <property name="use_underline">True</property> 1559 <property name="use_underline">True</property>
1501 <signal name="activate_item" handler="on_collection_delete_activate" last_modification_time="Mon, 23 May 2005 19:14:11 GMT"/> 1560 <signal name="activate_item" handler="on_collection_delete_clicked" last_modification_time="Mon, 23 May 2005 19:14:11 GMT"/>
1502 </widget> 1561 </widget>
1503 </child> 1562 </child>
1504 </widget> 1563 </widget>
@@ -1596,6 +1655,7 @@
1596 1655
1597 <child> 1656 <child>
1598 <widget class="GtkTreeView" id="clist1"> 1657 <widget class="GtkTreeView" id="clist1">
1658 <property agent="glademm" name="cxx_visibility">public</property>
1599 <property name="visible">True</property> 1659 <property name="visible">True</property>
1600 <property name="can_focus">True</property> 1660 <property name="can_focus">True</property>
1601 <property name="headers_visible">True</property> 1661 <property name="headers_visible">True</property>
@@ -1689,6 +1749,7 @@
1689 1749
1690 <child> 1750 <child>
1691 <widget class="GtkVBox" id="statisticsnotebookvbox"> 1751 <widget class="GtkVBox" id="statisticsnotebookvbox">
1752 <property agent="glademm" name="cxx_visibility">public</property>
1692 <property name="homogeneous">False</property> 1753 <property name="homogeneous">False</property>
1693 <property name="spacing">0</property> 1754 <property name="spacing">0</property>
1694 1755
@@ -1745,7 +1806,8 @@
1745 <property name="spacing">0</property> 1806 <property name="spacing">0</property>
1746 1807
1747 <child> 1808 <child>
1748 <widget class="GtkNotebook" id="notebook3"> 1809 <widget class="GtkNotebook" id="chatnotebook">
1810 <property agent="glademm" name="cxx_visibility">public</property>
1749 <property name="can_focus">True</property> 1811 <property name="can_focus">True</property>
1750 <property name="show_tabs">True</property> 1812 <property name="show_tabs">True</property>
1751 <property name="show_border">True</property> 1813 <property name="show_border">True</property>
@@ -1808,6 +1870,7 @@
1808 1870
1809 <child internal-child="entry"> 1871 <child internal-child="entry">
1810 <widget class="GtkEntry" id="chatMainEntryLine"> 1872 <widget class="GtkEntry" id="chatMainEntryLine">
1873 <property agent="glademm" name="cxx_visibility">public</property>
1811 <property name="visible">True</property> 1874 <property name="visible">True</property>
1812 <property name="can_focus">True</property> 1875 <property name="can_focus">True</property>
1813 <property name="editable">True</property> 1876 <property name="editable">True</property>
@@ -1817,8 +1880,8 @@
1817 <property name="has_frame">True</property> 1880 <property name="has_frame">True</property>
1818 <property name="invisible_char">*</property> 1881 <property name="invisible_char">*</property>
1819 <property name="activates_default">False</property> 1882 <property name="activates_default">False</property>
1820 <signal name="activate" handler="chatMainEntryLine_activate" last_modification_time="Mon, 23 May 2005 17:28:12 GMT"/> 1883 <signal name="activate" handler="chatMainEntryLine_clicked" last_modification_time="Mon, 23 May 2005 17:28:12 GMT"/>
1821 <signal name="editing_done" handler="on_chatMainEntryLine_editing_done" last_modification_time="Mon, 23 May 2005 17:28:16 GMT"/> 1884 <signal name="editing_done" handler="on_chatMainEntryLine_editing_done_clicked" last_modification_time="Mon, 23 May 2005 17:28:16 GMT"/>
1822 <accelerator key="Return" modifiers="0" signal="activate"/> 1885 <accelerator key="Return" modifiers="0" signal="activate"/>
1823 </widget> 1886 </widget>
1824 </child> 1887 </child>
@@ -1923,6 +1986,7 @@
1923 <property name="padding">0</property> 1986 <property name="padding">0</property>
1924 <property name="expand">False</property> 1987 <property name="expand">False</property>
1925 <property name="fill">False</property> 1988 <property name="fill">False</property>
1989 <property name="pack_type">GTK_PACK_END</property>
1926 </packing> 1990 </packing>
1927 </child> 1991 </child>
1928 </widget> 1992 </widget>
@@ -1976,7 +2040,7 @@
1976 <accessibility> 2040 <accessibility>
1977 <atkproperty name="AtkObject::accessible_name" translatable="yes">Delete button</atkproperty> 2041 <atkproperty name="AtkObject::accessible_name" translatable="yes">Delete button</atkproperty>
1978 </accessibility> 2042 </accessibility>
1979 <signal name="activate" handler="on_metaDataDialogDeleteButton_activate" last_modification_time="Mon, 23 May 2005 18:49:51 GMT"/> 2043 <signal name="activate" handler="on_metaDataDialogDeleteButton_clicked" object="metaDataDialog" last_modification_time="Mon, 23 May 2005 18:49:51 GMT"/>
1980 <accelerator key="Delete" modifiers="0" signal="activate"/> 2044 <accelerator key="Delete" modifiers="0" signal="activate"/>
1981 </widget> 2045 </widget>
1982 </child> 2046 </child>
@@ -2075,6 +2139,7 @@
2075 2139
2076 <child> 2140 <child>
2077 <widget class="GtkOptionMenu" id="optionmenu2"> 2141 <widget class="GtkOptionMenu" id="optionmenu2">
2142 <property agent="glademm" name="cxx_visibility">public</property>
2078 <property name="visible">True</property> 2143 <property name="visible">True</property>
2079 <property name="can_focus">True</property> 2144 <property name="can_focus">True</property>
2080 <property name="history">0</property> 2145 <property name="history">0</property>
@@ -2124,6 +2189,7 @@
2124 2189
2125 <child> 2190 <child>
2126 <widget class="GtkEntry" id="metaDataDialogValueEntry"> 2191 <widget class="GtkEntry" id="metaDataDialogValueEntry">
2192 <property agent="glademm" name="cxx_visibility">public</property>
2127 <property name="visible">True</property> 2193 <property name="visible">True</property>
2128 <property name="can_focus">True</property> 2194 <property name="can_focus">True</property>
2129 <property name="editable">True</property> 2195 <property name="editable">True</property>
@@ -2173,6 +2239,7 @@ Press ENTER to add the data.</atkproperty>
2173 2239
2174 <child> 2240 <child>
2175 <widget class="GtkTreeView" id="metaDataDialogMetaDataList"> 2241 <widget class="GtkTreeView" id="metaDataDialogMetaDataList">
2242 <property agent="glademm" name="cxx_visibility">public</property>
2176 <property name="visible">True</property> 2243 <property name="visible">True</property>
2177 <property name="can_focus">True</property> 2244 <property name="can_focus">True</property>
2178 <property name="headers_visible">True</property> 2245 <property name="headers_visible">True</property>
@@ -2241,6 +2308,7 @@ Press ENTER to add the data.</atkproperty>
2241 2308
2242 <child> 2309 <child>
2243 <widget class="GtkEntry" id="fileInformationKeywordEntry"> 2310 <widget class="GtkEntry" id="fileInformationKeywordEntry">
2311 <property agent="glademm" name="cxx_visibility">public</property>
2244 <property name="visible">True</property> 2312 <property name="visible">True</property>
2245 <property name="can_focus">True</property> 2313 <property name="can_focus">True</property>
2246 <property name="editable">True</property> 2314 <property name="editable">True</property>
@@ -2250,8 +2318,8 @@ Press ENTER to add the data.</atkproperty>
2250 <property name="has_frame">True</property> 2318 <property name="has_frame">True</property>
2251 <property name="invisible_char">*</property> 2319 <property name="invisible_char">*</property>
2252 <property name="activates_default">False</property> 2320 <property name="activates_default">False</property>
2253 <signal name="activate" handler="fileInformationKeywordEntry_activate" object="metaDataDialog" last_modification_time="Mon, 23 May 2005 17:23:09 GMT"/> 2321 <signal name="activate" handler="fileInformationKeywordEntry_clicked" object="metaDataDialog" last_modification_time="Mon, 23 May 2005 17:23:09 GMT"/>
2254 <signal name="editing_done" handler="fileInformationKeywordEntry_activate" object="metaDataDialog" last_modification_time="Mon, 23 May 2005 18:56:54 GMT"/> 2322 <signal name="editing_done" handler="fileInformationKeywordEntry_clicked" object="metaDataDialog" last_modification_time="Mon, 23 May 2005 18:56:54 GMT"/>
2255 <accelerator key="Return" modifiers="0" signal="activate"/> 2323 <accelerator key="Return" modifiers="0" signal="activate"/>
2256 </widget> 2324 </widget>
2257 <packing> 2325 <packing>
@@ -2288,6 +2356,7 @@ Press ENTER to add the data.</atkproperty>
2288 2356
2289 <child> 2357 <child>
2290 <widget class="GtkTreeView" id="metaDataDialogKeywordList"> 2358 <widget class="GtkTreeView" id="metaDataDialogKeywordList">
2359 <property agent="glademm" name="cxx_visibility">public</property>
2291 <property name="visible">True</property> 2360 <property name="visible">True</property>
2292 <property name="tooltip" translatable="yes">Select entries and use Delete button in order to delete keywords.</property> 2361 <property name="tooltip" translatable="yes">Select entries and use Delete button in order to delete keywords.</property>
2293 <property name="can_focus">True</property> 2362 <property name="can_focus">True</property>
@@ -2398,6 +2467,7 @@ Press ENTER to add the data.</atkproperty>
2398 2467
2399 <child> 2468 <child>
2400 <widget class="GtkTreeView" id="clist10"> 2469 <widget class="GtkTreeView" id="clist10">
2470 <property agent="glademm" name="cxx_visibility">public</property>
2401 <property name="visible">True</property> 2471 <property name="visible">True</property>
2402 <property name="can_focus">True</property> 2472 <property name="can_focus">True</property>
2403 <property name="headers_visible">True</property> 2473 <property name="headers_visible">True</property>
@@ -2453,13 +2523,15 @@ Press ENTER to add the data.</atkproperty>
2453 <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> 2523 <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
2454 2524
2455 <child> 2525 <child>
2456 <widget class="GtkScrolledWindow" id="scrolledwindow14"> 2526 <widget class="GtkScrolledWindow" id="searchPageScrolledWindow">
2527 <property agent="glademm" name="cxx_visibility">public</property>
2457 <property name="visible">True</property> 2528 <property name="visible">True</property>
2458 <property name="can_focus">True</property> 2529 <property name="can_focus">True</property>
2459 <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> 2530 <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
2460 <property name="vscrollbar_policy">GTK_POLICY_NEVER</property> 2531 <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
2461 <property name="shadow_type">GTK_SHADOW_NONE</property> 2532 <property name="shadow_type">GTK_SHADOW_NONE</property>
2462 <property name="window_placement">GTK_CORNER_TOP_LEFT</property> 2533 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
2534 <signal name="destroy" handler="on_searchPageScrolledWindow_destroy" object="searchPageScrolledWindow" last_modification_time="Thu, 26 May 2005 22:41:04 GMT"/>
2463 2535
2464 <child> 2536 <child>
2465 <widget class="GtkViewport" id="viewport5"> 2537 <widget class="GtkViewport" id="viewport5">
@@ -2483,6 +2555,7 @@ Press ENTER to add the data.</atkproperty>
2483 2555
2484 <child> 2556 <child>
2485 <widget class="GtkTreeView" id="searchResults"> 2557 <widget class="GtkTreeView" id="searchResults">
2558 <property agent="glademm" name="cxx_visibility">public</property>
2486 <property name="visible">True</property> 2559 <property name="visible">True</property>
2487 <property name="can_focus">True</property> 2560 <property name="can_focus">True</property>
2488 <property name="headers_visible">True</property> 2561 <property name="headers_visible">True</property>
@@ -2506,64 +2579,95 @@ Press ENTER to add the data.</atkproperty>
2506 <property name="relief">GTK_RELIEF_NORMAL</property> 2579 <property name="relief">GTK_RELIEF_NORMAL</property>
2507 <property name="focus_on_click">True</property> 2580 <property name="focus_on_click">True</property>
2508 <signal name="clicked" handler="on_downloadButton_clicked" object="searchResults" last_modification_time="Mon, 23 May 2005 18:59:36 GMT"/> 2581 <signal name="clicked" handler="on_downloadButton_clicked" object="searchResults" last_modification_time="Mon, 23 May 2005 18:59:36 GMT"/>
2582 <signal name="activate" handler="on_downloadButton_clicked" object="searchResults" last_modification_time="Thu, 26 May 2005 09:26:15 GMT"/>
2509 <accelerator key="Return" modifiers="GDK_CONTROL_MASK" signal="activate"/> 2583 <accelerator key="Return" modifiers="GDK_CONTROL_MASK" signal="activate"/>
2510 2584
2511 <child> 2585 <child>
2512 <widget class="GtkAlignment" id="alignment3"> 2586 <widget class="GtkHBox" id="hbox23">
2513 <property name="visible">True</property> 2587 <property name="visible">True</property>
2514 <property name="xalign">0.5</property> 2588 <property name="homogeneous">False</property>
2515 <property name="yalign">0.5</property> 2589 <property name="spacing">0</property>
2516 <property name="xscale">0</property>
2517 <property name="yscale">0</property>
2518 <property name="top_padding">0</property>
2519 <property name="bottom_padding">0</property>
2520 <property name="left_padding">0</property>
2521 <property name="right_padding">0</property>
2522 2590
2523 <child> 2591 <child>
2524 <widget class="GtkHBox" id="hbox13"> 2592 <widget class="GtkAlignment" id="alignment3">
2525 <property name="visible">True</property> 2593 <property name="visible">True</property>
2526 <property name="homogeneous">False</property> 2594 <property name="xalign">0.5</property>
2527 <property name="spacing">2</property> 2595 <property name="yalign">0.5</property>
2596 <property name="xscale">0</property>
2597 <property name="yscale">0</property>
2598 <property name="top_padding">0</property>
2599 <property name="bottom_padding">0</property>
2600 <property name="left_padding">0</property>
2601 <property name="right_padding">0</property>
2528 2602
2529 <child> 2603 <child>
2530 <widget class="GtkImage" id="image3"> 2604 <widget class="GtkHBox" id="hbox13">
2531 <property name="visible">True</property> 2605 <property name="visible">True</property>
2532 <property name="stock">gtk-copy</property> 2606 <property name="homogeneous">False</property>
2533 <property name="icon_size">4</property> 2607 <property name="spacing">2</property>
2534 <property name="xalign">0.5</property>
2535 <property name="yalign">0.5</property>
2536 <property name="xpad">0</property>
2537 <property name="ypad">0</property>
2538 </widget>
2539 <packing>
2540 <property name="padding">0</property>
2541 <property name="expand">False</property>
2542 <property name="fill">False</property>
2543 </packing>
2544 </child>
2545 2608
2546 <child> 2609 <child>
2547 <widget class="GtkLabel" id="label65"> 2610 <widget class="GtkImage" id="image3">
2548 <property name="visible">True</property> 2611 <property name="visible">True</property>
2549 <property name="label" translatable="yes">_Download</property> 2612 <property name="stock">gtk-copy</property>
2550 <property name="use_underline">True</property> 2613 <property name="icon_size">4</property>
2551 <property name="use_markup">False</property> 2614 <property name="xalign">0.5</property>
2552 <property name="justify">GTK_JUSTIFY_LEFT</property> 2615 <property name="yalign">0.5</property>
2553 <property name="wrap">False</property> 2616 <property name="xpad">0</property>
2554 <property name="selectable">False</property> 2617 <property name="ypad">0</property>
2555 <property name="xalign">0.5</property> 2618 </widget>
2556 <property name="yalign">0.5</property> 2619 <packing>
2557 <property name="xpad">0</property> 2620 <property name="padding">0</property>
2558 <property name="ypad">0</property> 2621 <property name="expand">False</property>
2622 <property name="fill">False</property>
2623 </packing>
2624 </child>
2625
2626 <child>
2627 <widget class="GtkLabel" id="label65">
2628 <property name="visible">True</property>
2629 <property name="label" translatable="yes">_Download</property>
2630 <property name="use_underline">True</property>
2631 <property name="use_markup">False</property>
2632 <property name="justify">GTK_JUSTIFY_LEFT</property>
2633 <property name="wrap">False</property>
2634 <property name="selectable">False</property>
2635 <property name="xalign">0.5</property>
2636 <property name="yalign">0.5</property>
2637 <property name="xpad">0</property>
2638 <property name="ypad">0</property>
2639 </widget>
2640 <packing>
2641 <property name="padding">0</property>
2642 <property name="expand">False</property>
2643 <property name="fill">False</property>
2644 </packing>
2645 </child>
2559 </widget> 2646 </widget>
2560 <packing>
2561 <property name="padding">0</property>
2562 <property name="expand">False</property>
2563 <property name="fill">False</property>
2564 </packing>
2565 </child> 2647 </child>
2566 </widget> 2648 </widget>
2649 <packing>
2650 <property name="padding">0</property>
2651 <property name="expand">True</property>
2652 <property name="fill">True</property>
2653 </packing>
2654 </child>
2655
2656 <child>
2657 <widget class="GtkButton" id="closeSearchButton">
2658 <property name="visible">True</property>
2659 <property name="can_focus">True</property>
2660 <property name="label">gtk-close</property>
2661 <property name="use_stock">True</property>
2662 <property name="relief">GTK_RELIEF_NORMAL</property>
2663 <property name="focus_on_click">True</property>
2664 <signal name="clicked" handler="on_closeSearchButton_clicked" object="searchPageScrolledWindow" last_modification_time="Thu, 26 May 2005 22:42:37 GMT"/>
2665 </widget>
2666 <packing>
2667 <property name="padding">0</property>
2668 <property name="expand">True</property>
2669 <property name="fill">True</property>
2670 </packing>
2567 </child> 2671 </child>
2568 </widget> 2672 </widget>
2569 </child> 2673 </child>
@@ -2613,6 +2717,7 @@ Press ENTER to add the data.</atkproperty>
2613 2717
2614 <child> 2718 <child>
2615 <widget class="GtkTreeView" id="namespaceContentFrameTreeView"> 2719 <widget class="GtkTreeView" id="namespaceContentFrameTreeView">
2720 <property agent="glademm" name="cxx_visibility">public</property>
2616 <property name="visible">True</property> 2721 <property name="visible">True</property>
2617 <property name="can_focus">True</property> 2722 <property name="can_focus">True</property>
2618 <property name="headers_visible">True</property> 2723 <property name="headers_visible">True</property>
@@ -2642,7 +2747,7 @@ Press ENTER to add the data.</atkproperty>
2642 <property name="can_focus">True</property> 2747 <property name="can_focus">True</property>
2643 <property name="relief">GTK_RELIEF_NORMAL</property> 2748 <property name="relief">GTK_RELIEF_NORMAL</property>
2644 <property name="focus_on_click">True</property> 2749 <property name="focus_on_click">True</property>
2645 <signal name="clicked" handler="on_namespaceInsertButton_activate" object="namespaceContentFrame" last_modification_time="Mon, 23 May 2005 19:00:01 GMT"/> 2750 <signal name="clicked" handler="on_namespaceInsertButton_clicked" object="namespaceContentFrame" last_modification_time="Mon, 23 May 2005 19:00:01 GMT"/>
2646 2751
2647 <child> 2752 <child>
2648 <widget class="GtkAlignment" id="alignment4"> 2753 <widget class="GtkAlignment" id="alignment4">
@@ -2718,7 +2823,7 @@ Press ENTER to add the data.</atkproperty>
2718 <property name="can_focus">True</property> 2823 <property name="can_focus">True</property>
2719 <property name="relief">GTK_RELIEF_NORMAL</property> 2824 <property name="relief">GTK_RELIEF_NORMAL</property>
2720 <property name="focus_on_click">False</property> 2825 <property name="focus_on_click">False</property>
2721 <signal name="clicked" handler="on_namespaceUpdateButton_clicked" object="namespaceContentFrameTreeView" last_modification_time="Mon, 23 May 2005 19:01:59 GMT"/> 2826 <signal name="clicked" handler="on_namespaceUpdateButton_clicked" object="namespaceContentFrame" last_modification_time="Mon, 23 May 2005 19:01:59 GMT"/>
2722 2827
2723 <child> 2828 <child>
2724 <widget class="GtkAlignment" id="alignment5"> 2829 <widget class="GtkAlignment" id="alignment5">
@@ -2835,6 +2940,7 @@ Press ENTER to add the data.</atkproperty>
2835 2940
2836 <child> 2941 <child>
2837 <widget class="GtkTextView" id="chatLogViewer"> 2942 <widget class="GtkTextView" id="chatLogViewer">
2943 <property agent="glademm" name="cxx_visibility">public</property>
2838 <property name="visible">True</property> 2944 <property name="visible">True</property>
2839 <property name="can_focus">True</property> 2945 <property name="can_focus">True</property>
2840 <property name="editable">True</property> 2946 <property name="editable">True</property>
@@ -2868,6 +2974,7 @@ Press ENTER to add the data.</atkproperty>
2868 2974
2869 <child> 2975 <child>
2870 <widget class="GtkComboBoxEntry" id="chatLineTextEntry"> 2976 <widget class="GtkComboBoxEntry" id="chatLineTextEntry">
2977 <property agent="glademm" name="cxx_visibility">public</property>
2871 <property name="visible">True</property> 2978 <property name="visible">True</property>
2872 <property name="items" translatable="yes">/join #gnunet</property> 2979 <property name="items" translatable="yes">/join #gnunet</property>
2873 <signal name="editing_done" handler="on_chatLineTextEntry_editing_done" last_modification_time="Mon, 23 May 2005 17:18:48 GMT"/> 2980 <signal name="editing_done" handler="on_chatLineTextEntry_editing_done" last_modification_time="Mon, 23 May 2005 17:18:48 GMT"/>
@@ -2980,7 +3087,8 @@ Press ENTER to add the data.</atkproperty>
2980 <property name="window_placement">GTK_CORNER_TOP_LEFT</property> 3087 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
2981 3088
2982 <child> 3089 <child>
2983 <widget class="GtkTreeView" id="treeview3"> 3090 <widget class="GtkTreeView" id="chatUserListTreeView">
3091 <property agent="glademm" name="cxx_visibility">public</property>
2984 <property name="visible">True</property> 3092 <property name="visible">True</property>
2985 <property name="can_focus">True</property> 3093 <property name="can_focus">True</property>
2986 <property name="headers_visible">True</property> 3094 <property name="headers_visible">True</property>
diff --git a/src/Makefile.am b/src/Makefile.am
index bd993c58..1f37d08e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,12 +9,21 @@ AM_CFLAGS = \
9 -DGLADE_FILE="\"$(DESTDIR)$(pkgdatadir)/gnunet-gtk.glade\"" 9 -DGLADE_FILE="\"$(DESTDIR)$(pkgdatadir)/gnunet-gtk.glade\""
10 10
11gnunet_gtk_SOURCES = \ 11gnunet_gtk_SOURCES = \
12 main.c main.h gettext.h 12 about.c \
13 daemon.c daemon.h \
14 fs.c fs.h \
15 gettext.h \
16 gtk26about.c gtk26about.h \
17 helper.c helper.h \
18 main.c main.h \
19 platform.h plibc.h \
20 search.c
13 21
14gnunet_gtk_LDADD = \ 22gnunet_gtk_LDADD = \
15 @GTK_LIBS@ \ 23 @GTK_LIBS@ \
16 @GNUNETGTK_LIBS@ \ 24 @GNUNETGTK_LIBS@ \
17 $(INTLLIBS) 25 $(INTLLIBS) \
26 -lgthread-2.0
18 27
19gnunet_gtk_LDFLAGS = \ 28gnunet_gtk_LDFLAGS = \
20 -export-dynamic 29 -export-dynamic
diff --git a/src/about.c b/src/about.c
new file mode 100644
index 00000000..bd41cbac
--- /dev/null
+++ b/src/about.c
@@ -0,0 +1,125 @@
1/*
2 This file is part of GNUnet
3
4 GNUnet is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published
6 by the Free Software Foundation; either version 2, or (at your
7 option) any later version.
8
9 GNUnet is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNUnet; see the file COPYING. If not, write to the
16 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20/**
21 * @file src/applications/afs/gtkui/about.c
22 * @author Christian Grothoff
23 * @author Igor Wronsky
24 *
25 * This file contains the about dialog.
26 */
27
28#include "config.h"
29#include "gettext.h"
30#include <gdk-pixbuf/gdk-pixbuf.h>
31#include "gtk26about.h"
32
33#include "helper.h"
34
35/**
36 * This displays an about window
37 *
38 * Todo: the GTK demo can do links.
39 */
40void on_about_clicked(GtkWidget *dummy,
41 gpointer data) {
42 const gchar * authors[] = {
43 "Juergen Appel <jappel@linux01.gwdg.de>",
44 "Krista Bennett <kbennett@cerias.purdue.edu>",
45 "James Blackwell <jblack@linuxguru.net>",
46 "Ludovic Courtes <ludo@chbouib.org>",
47 "Nils Durner <N.Durner@t-online.de>",
48 "Renaldo Ferreira <rf@cs.purdue.edu>",
49 "Christian Grothoff <christian@grothoff.org>",
50 "Eric Haumant",
51 "Tzvetan Horozov <horozov@motorola.com>",
52 "Gerd Knorr <kraxel@bytesex.org>",
53 "Werner Koch <libgcrypt@g10code.com>",
54 "Uli Luckas <luckas@musoft.de>",
55 "Blake Matheny <bmatheny@purdue.edu>",
56 "Glenn McGrath <bug1@iinet.net.au>",
57 "Hendrik Pagenhardt <Hendrik.Pagenhardt@gmx.net>",
58 "Ioana Patrascu <ioanapatrascu@yahoo.com>",
59 "Marko Raeihae",
60 "Paul Ruth <ruth@cs.purdue.edu>",
61 "Risto Saarelma",
62 "Antti Salonen",
63 "Tiberius Stef <tstef@cs.purdue.edu>",
64 "Tuomas Toivonen",
65 "Tomi Tukiainen",
66 "Kevin Vandersloot <kfv101@psu.edu>",
67 "Simo Viitanen",
68 "Larry Waldo",
69 "Igor Wronsky <iwronsky@users.sourceforge.net>",
70 "<january@hushmail.com>",
71 NULL,
72 };
73 const gchar * artists[] = {
74 "Christian Muellner <chris@flop.de>",
75 "Alex Jones <alexrjones@ntlworld.com>",
76 NULL,
77 };
78 const char * trans = _("translator-credits");
79 const char * license = "GNUnet is free software; you can redistribute it and/or modify\n"
80 "it under the terms of the GNU General Public License as published\n"
81 "by the Free Software Foundation; either version 2, or (at your\n"
82 "option) any later version.\n\n"
83 "GNUnet is distributed in the hope that it will be useful, but\n"
84 "WITHOUT ANY WARRANTY; without even the implied warranty of\n"
85 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
86 "See the GNU General Public License for more details.\n\n"
87 "You should have received a copy of the GNU General Public License\n"
88 "along with GNUnet; see the file COPYING. If not, write to the\n"
89 "Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n"
90 "Boston, MA 02111-1307, USA.\n";
91
92 GdkPixbuf * logo;
93 GError * error;
94
95 error = NULL;
96 logo = gdk_pixbuf_new_from_file("gnunet_logo.png",
97 &error);
98 if (logo != NULL) {
99 gtk_show_about_dialog(NULL,
100 "logo", logo,
101 "name", "gnunet-gtk",
102 "version", VERSION,
103 "copyright" , "(C) 2001-2005 Christian Grothoff (and other contributing authors)",
104 "website", "http://www.gnu.org/software/gnunet/",
105 "license", license,
106 "authors", authors,
107 "artists", artists,
108 (0 == strcmp(trans,"translator-credits")) ? NULL : "translator_credits", trans,
109 NULL);
110 g_object_unref(G_OBJECT(logo));
111 } else {
112 gtk_show_about_dialog(NULL,
113 "name", "gnunet-gtk",
114 "version", VERSION,
115 "copyright" , "(C) 2001-2005 Christian Grothoff (and other contributing authors)",
116 "website", "http://www.gnu.org/software/gnunet/",
117 "license", license,
118 "authors", authors,
119 "artists", artists,
120 (0 == strcmp(trans,"translator-credits")) ? NULL : "translator_credits", trans,
121 NULL);
122 }
123}
124
125/* end of about.c */
diff --git a/src/daemon.c b/src/daemon.c
new file mode 100644
index 00000000..f3949276
--- /dev/null
+++ b/src/daemon.c
@@ -0,0 +1,315 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/daemon.c
23 * @brief code for gnunet-gtk gnunetd interaction
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "daemon.h"
29#include "main.h"
30#include "helper.h"
31#ifndef MINGW
32 #include <sys/wait.h>
33#endif
34#include <GNUnet/gnunet_util.h>
35#include <GNUnet/gnunet_protocols.h>
36
37/**
38 * Checks if gnunetd is running
39 *
40 * NOTE: Uses CS_PROTO_CLIENT_COUNT query to determine if
41 * gnunetd is running
42 */
43static int checkDaemonRunning(void) {
44 GNUNET_TCP_SOCKET * sock;
45 CS_HEADER csHdr;
46 int ret;
47
48 sock = getClientSocket();
49 if(sock == NULL) {
50 BREAK();
51 return SYSERR;
52 }
53
54 csHdr.size
55 = htons(sizeof(CS_HEADER));
56 csHdr.type
57 = htons(CS_PROTO_CLIENT_COUNT);
58 if (SYSERR == writeToSocket(sock,
59 &csHdr)) {
60 LOG(LOG_DEBUG,
61 _("gnunetd is NOT running.\n"));
62 releaseClientSocket(sock);
63 return SYSERR;
64 }
65 if (SYSERR == readTCPResult(sock,
66 &ret)) {
67 releaseClientSocket(sock);
68 return SYSERR;
69 }
70 releaseClientSocket(sock);
71
72 return OK;
73}
74
75
76
77#if LINUX || OSX || SOLARIS || SOMEBSD
78static int launchWithExec() {
79 pid_t pid;
80
81 pid = fork();
82 if (pid == 0) {
83 char * args[4];
84 char * path;
85 char * cp;
86
87 path = NULL;
88 cp = getConfigurationString("MAIN",
89 "ARGV[0]");
90 if (cp != NULL) {
91 int i = strlen(cp);
92 while ( (i >= 0) &&
93 (cp[i] != DIR_SEPARATOR) )
94 i--;
95 if ( i != -1 ) {
96 cp[i+1] = '\0';
97 path = MALLOC(i+1+strlen("gnunetd"));
98 strcpy(path, cp);
99 strcat(path, "gnunetd");
100 args[0] = path;
101 FREE(cp);
102 } else {
103 args[0] = "gnunetd";
104 }
105 }
106 cp = getConfigurationString("GNUNET-GTK",
107 "GNUNETD-CONFIG");
108 if (cp != NULL) {
109 args[1] = "-c";
110 args[2] = cp;
111 } else {
112 args[1] = NULL;
113 }
114 args[3] = NULL;
115 errno = 0;
116 nice(10); /* return value is not well-defined */
117 if (errno != 0)
118 LOG_STRERROR(LOG_WARNING, "nice");
119 if (path != NULL)
120 execv(path,
121 args);
122 else
123 execvp("gnunetd",
124 args);
125 LOG_STRERROR(LOG_FAILURE, "exec");
126 LOG(LOG_FAILURE,
127 _("Attempted path to '%s' was '%s'.\n"),
128 "gnunetd",
129 (path == NULL) ? "gnunetd" : path);
130 FREENONNULL(path); /* yeah, right, like we're likely to get
131 here... */
132 FREENONNULL(args[1]);
133 _exit(-1);
134 } else {
135 pid_t ret;
136 int status;
137
138 ret = waitpid(pid, &status, 0);
139 if (ret == -1) {
140 LOG_STRERROR(LOG_ERROR, "waitpid");
141 return SYSERR;
142 }
143 if ( (WIFEXITED(status) &&
144 (0 != WEXITSTATUS(status)) ) ) {
145 guiMessage(_("Starting gnunetd failed, error code: %d"),
146 WEXITSTATUS(status));
147 return SYSERR;
148 }
149#ifdef WCOREDUMP
150 if (WCOREDUMP(status)) {
151 guiMessage(_("Starting gnunetd failed (core dumped)."));
152 return SYSERR;
153 }
154#endif
155 if (WIFSIGNALED(status) ||
156 WTERMSIG(status) ) {
157 guiMessage(_("Starting gnunetd failed (aborted by signal)."));
158 return SYSERR;
159 }
160 return OK;
161 }
162}
163#endif
164
165static int doLaunch() {
166
167#if LINUX || OSX || SOLARIS || SOMEBSD
168 return launchWithExec();
169#elif MINGW
170 char szCall[_MAX_PATH + 1], szWd[_MAX_PATH + 1], szCWd[_MAX_PATH + 1];
171 char *args[1];
172
173 conv_to_win_path("/bin/gnunetd.exe", szCall);
174 conv_to_win_path("/bin", szWd);
175 _getcwd(szCWd, _MAX_PATH);
176
177 chdir(szWd);
178 args[0] = NULL;
179 spawnvp(_P_NOWAIT, szCall, (const char *const *) args);
180 chdir(szCWd);
181
182 return OK;
183#else
184 /* any system out there that does not support THIS!? */
185 system("gnunetd"); /* we may not have nice,
186 so let's be minimalistic here. */
187 return OK;
188#endif
189}
190
191/**
192 * Launch gnunetd w/ checks
193 */
194void on_startDaemon_clicked(GtkWidget * widget,
195 gpointer data) {
196 if (OK == checkDaemonRunning() ) {
197 cronCheckDaemon(NULL);
198 return;
199 } else {
200 addLogEntry(_("Launching gnunetd..."));
201 doLaunch();
202 }
203}
204
205/**
206 * Kill gnunetd
207 */
208void on_stopDaemon_clicked(GtkWidget * widget,
209 gpointer data) {
210 if (OK == checkDaemonRunning() ) {
211 GNUNET_TCP_SOCKET * sock;
212 CS_HEADER csHdr;
213 int ret;
214
215 sock = getClientSocket();
216 if (sock == NULL) {
217 cronCheckDaemon(NULL);
218 /* well, probably already dead */
219 return;
220 }
221 csHdr.size
222 = htons(sizeof(CS_HEADER));
223 csHdr.type
224 = htons(CS_PROTO_SHUTDOWN_REQUEST);
225 if (SYSERR == writeToSocket(sock,
226 &csHdr)) {
227 guiMessage(_("Error sending shutdown request to gnunetd."));
228 releaseClientSocket(sock);
229 cronCheckDaemon(NULL);
230 return;
231 }
232 if (SYSERR == readTCPResult(sock,
233 &ret)) {
234 guiMessage(_("Error reading shutdown confirmation from gnunetd."));
235 releaseClientSocket(sock);
236 cronCheckDaemon(NULL);
237 return;
238 }
239 if (ret == OK) {
240 static GtkWidget * killEntry;
241 killEntry
242 = glade_xml_get_widget(mainXML,
243 "stopDaemon");
244 gtk_widget_set_sensitive(killEntry, FALSE);
245 addLogEntry(_("Terminating gnunetd..."));
246 } else {
247 guiMessage(_("gnunetd refused to shut down (error code '%d')."),
248 ret);
249 }
250 releaseClientSocket(sock);
251 }
252 cronCheckDaemon(NULL);
253}
254
255static gint doUpdateMenus(SaveCall * call) {
256 static GtkWidget * killEntry = NULL;
257 static GtkWidget * launchEntry = NULL;
258 static GtkWidget * statsEntryYes = NULL;
259 static GtkWidget * statsEntryNo = NULL;
260 static int once = 1;
261 static int isLocal;
262 char * host;
263 int ret;
264
265 ret = * (int*) call->args;
266 if (once) {
267 once = 0;
268 killEntry
269 = glade_xml_get_widget(mainXML,
270 "stopDaemon");
271 launchEntry
272 = glade_xml_get_widget(mainXML,
273 "startDaemon");
274 statsEntryYes
275 = glade_xml_get_widget(mainXML,
276 "statusPixmapYes");
277 statsEntryNo
278 = glade_xml_get_widget(mainXML,
279 "statusPixmapNo");
280 host = getConfigurationString("NETWORK",
281 "HOST");
282 if ( (host == NULL) ||
283 (strcmp(host, "localhost")==0) )
284 isLocal = TRUE;
285 else
286 isLocal = FALSE;
287 FREENONNULL(host);
288 }
289 if (ret == SYSERR) {
290 gtk_widget_hide(statsEntryYes);
291 gtk_widget_show_all(statsEntryNo);
292 gtk_widget_set_sensitive(killEntry, FALSE);
293 gtk_widget_set_sensitive(launchEntry, (TRUE & isLocal) );
294 } else {
295 gtk_widget_hide(statsEntryNo);
296 gtk_widget_show_all(statsEntryYes);
297 gtk_widget_set_sensitive(killEntry, TRUE);
298 gtk_widget_set_sensitive(launchEntry, FALSE);
299 }
300 gtkSaveCallDone(call->sem);
301 return FALSE;
302}
303
304void cronCheckDaemon(void * dummy) {
305 static int last = 42;
306 int ret;
307
308 ret = checkDaemonRunning();
309 if (ret != last) {
310 last = ret;
311 gtkSaveCall((GtkFunction) doUpdateMenus, &ret);
312 }
313}
314
315/* end of daemon.c */
diff --git a/src/daemon.h b/src/daemon.h
new file mode 100644
index 00000000..9ff68267
--- /dev/null
+++ b/src/daemon.h
@@ -0,0 +1,33 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/daemon.h
23 * @brief code for gnunet-gtk gnunetd interaction
24 * @author Christian Grothoff
25 */
26
27
28#ifndef GTK_DAEMON_H
29#define GTK_DAEMON_H
30
31void cronCheckDaemon(void * dummy);
32
33#endif
diff --git a/src/fs.c b/src/fs.c
new file mode 100644
index 00000000..d59879f7
--- /dev/null
+++ b/src/fs.c
@@ -0,0 +1,54 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/fs.c
23 * @brief main file-sharing code of gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#include "fs.h"
28
29
30struct FSUI_Context * ctx;
31
32/**
33 * FSUI event handler.
34 */
35static void eventProcessor(void * cls,
36 const FSUI_Event * event) {
37 printf("FSUI event received!\n");
38}
39
40void gtk_fs_init() {
41 /* FSUI initialization here! */
42 ctx = FSUI_start("gnunet-gtk",
43 YES,
44 &eventProcessor,
45 NULL);
46 fs_search_start();
47}
48
49void gtk_fs_done() {
50 fs_search_stop();
51 FSUI_stop(ctx);
52}
53
54/* end of fs.c */
diff --git a/src/fs.h b/src/fs.h
new file mode 100644
index 00000000..ca401292
--- /dev/null
+++ b/src/fs.h
@@ -0,0 +1,39 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/fs.h
23 * @brief file-sharing globals of gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#ifndef GTK_FS_H
28#define GTK_FS_H
29
30#include <GNUnet/gnunet_ecrs_lib.h>
31#include <GNUnet/gnunet_fsui_lib.h>
32
33extern struct FSUI_Context * ctx;
34
35void gtk_fs_init(void);
36
37void gtk_fs_done(void);
38
39#endif
diff --git a/src/gtk26about.c b/src/gtk26about.c
new file mode 100644
index 00000000..9228caa2
--- /dev/null
+++ b/src/gtk26about.c
@@ -0,0 +1,1846 @@
1/* GTK - The GIMP Toolkit
2 * Copyright (C) 2001 CodeFactory AB
3 * Copyright (C) 2001, 2002 Anders Carlsson
4 * Copyright (C) 2003, 2004 Matthias Clasen <mclasen@redhat.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22/*
23 * Author: Anders Carlsson <andersca@gnu.org>
24 *
25 * Modified by the GTK+ Team and others 1997-2004. See the AUTHORS
26 * file for a list of people on the GTK+ Team. See the ChangeLog
27 * files for a list of changes. These files are distributed with
28 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
29 */
30
31#include "platform.h"
32#include "gtk26about.h"
33#include <string.h>
34#include <gdk/gdkkeysyms.h>
35#include <gtk/gtk.h>
36#include <gtk/gtktext.h>
37
38typedef struct _GtkAboutDialogPrivate GtkAboutDialogPrivate;
39struct _GtkAboutDialogPrivate
40{
41 gchar *name;
42 gchar *version;
43 gchar *copyright;
44 gchar *comments;
45 gchar *website;
46 gchar *website_label;
47 gchar *translator_credits;
48 gchar *license;
49
50 gchar **authors;
51 gchar **documenters;
52 gchar **artists;
53
54 GtkWidget *logo_image;
55 GtkWidget *name_label;
56 GtkWidget *comments_label;
57 GtkWidget *copyright_label;
58 GtkWidget *website_button;
59
60 GtkWidget *credits_button;
61 GtkWidget *credits_dialog;
62 GtkWidget *license_button;
63 GtkWidget *license_dialog;
64
65 GdkCursor *hand_cursor;
66 GdkCursor *regular_cursor;
67 gboolean hovering_over_link;
68};
69
70#define GTK_ABOUT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ABOUT_DIALOG, GtkAboutDialogPrivate))
71
72
73enum
74{
75 PROP_0,
76 PROP_NAME,
77 PROP_VERSION,
78 PROP_COPYRIGHT,
79 PROP_COMMENTS,
80 PROP_WEBSITE,
81 PROP_WEBSITE_LABEL,
82 PROP_LICENSE,
83 PROP_AUTHORS,
84 PROP_DOCUMENTERS,
85 PROP_TRANSLATOR_CREDITS,
86 PROP_ARTISTS,
87 PROP_LOGO
88};
89
90static void gtk_about_dialog_finalize (GObject *object);
91static void gtk_about_dialog_get_property (GObject *object,
92 guint prop_id,
93 GValue *value,
94 GParamSpec *pspec);
95static void gtk_about_dialog_set_property (GObject *object,
96 guint prop_id,
97 const GValue *value,
98 GParamSpec *pspec);
99static void update_name_version (GtkAboutDialog *about);
100static GtkIconSet * icon_set_new_from_pixbufs (GList *pixbufs);
101static void activate_url (GtkWidget *widget,
102 gpointer data);
103static void set_link_button_text (GtkWidget *about,
104 GtkWidget *button,
105 gchar *text);
106static GtkWidget * create_link_button (GtkWidget *about,
107 gchar *text,
108 gchar *url,
109 GCallback callback,
110 gpointer data);
111static void follow_if_link (GtkAboutDialog *about,
112 GtkTextIter *iter);
113static void set_cursor_if_appropriate (GtkAboutDialog *about,
114 GtkTextView *text_view,
115 gint x,
116 gint y);
117static void add_credits_page (GtkAboutDialog *about,
118 GtkWidget *notebook,
119 gchar *title,
120 gchar **people);
121static gboolean credits_key_press_event (GtkWidget *text_view,
122 GdkEventKey *event,
123 GtkAboutDialog *about);
124static gboolean credits_event_after (GtkWidget *text_view,
125 GdkEvent *event,
126 GtkAboutDialog *about);
127static gboolean credits_motion_notify_event (GtkWidget *text_view,
128 GdkEventMotion *event,
129 GtkAboutDialog *about);
130static gboolean credits_visibility_notify_event (GtkWidget *text_view,
131 GdkEventVisibility *event,
132 GtkAboutDialog *about);
133static void display_credits_dialog (GtkWidget *button,
134 gpointer data);
135static void display_license_dialog (GtkWidget *button,
136 gpointer data);
137
138
139static GtkAboutDialogActivateLinkFunc activate_email_hook = NULL;
140static GtkAboutDialogActivateLinkFunc activate_url_hook = NULL;
141
142G_DEFINE_TYPE (GtkAboutDialog, gtk_about_dialog, GTK_TYPE_DIALOG);
143
144static void
145gtk_about_dialog_class_init (GtkAboutDialogClass *klass)
146{
147 GObjectClass *object_class;
148 GtkWidgetClass *widget_class;
149 GtkDialogClass *dialog_class;
150
151 object_class = (GObjectClass *)klass;
152 widget_class = (GtkWidgetClass *)klass;
153 dialog_class = (GtkDialogClass *)klass;
154
155 object_class->set_property = gtk_about_dialog_set_property;
156 object_class->get_property = gtk_about_dialog_get_property;
157
158 object_class->finalize = gtk_about_dialog_finalize;
159
160 g_object_class_install_property (object_class,
161 PROP_NAME,
162 g_param_spec_string ("name",
163 gettext_noop("Program name"),
164 gettext_noop("The name of the program. If this is not set, it defaults to g_get_application_name()"),
165 NULL,
166 G_PARAM_READWRITE));
167
168 g_object_class_install_property (object_class,
169 PROP_VERSION,
170 g_param_spec_string ("version",
171 gettext_noop("Program version"),
172 gettext_noop("The version of the program"),
173 NULL,
174 G_PARAM_READWRITE));
175 g_object_class_install_property (object_class,
176 PROP_COPYRIGHT,
177 g_param_spec_string ("copyright",
178 gettext_noop("Copyright string"),
179 gettext_noop("Copyright information for the program"),
180 NULL,
181 G_PARAM_READWRITE));
182
183 g_object_class_install_property (object_class,
184 PROP_COMMENTS,
185 g_param_spec_string ("comments",
186 gettext_noop("Comments string"),
187 gettext_noop("Comments about the program"),
188 NULL,
189 G_PARAM_READWRITE));
190 g_object_class_install_property (object_class,
191 PROP_LICENSE,
192 g_param_spec_string ("license",
193 gettext_noop("License"),
194 gettext_noop("The license of the program"),
195 NULL,
196 G_PARAM_READWRITE));
197
198 g_object_class_install_property (object_class,
199 PROP_WEBSITE,
200 g_param_spec_string ("website",
201 gettext_noop("Website URL"),
202 gettext_noop("The URL for the link to the website of the program"),
203 NULL,
204 G_PARAM_READWRITE));
205
206 g_object_class_install_property (object_class,
207 PROP_WEBSITE_LABEL,
208 g_param_spec_string ("website_label",
209 gettext_noop("Website label"),
210 gettext_noop("The label for the link to the website of the program. If this is not set, it defaults to the URL"),
211 NULL,
212 G_PARAM_READWRITE));
213
214 g_object_class_install_property (object_class,
215 PROP_AUTHORS,
216 g_param_spec_boxed ("authors",
217 gettext_noop("Authors"),
218 gettext_noop("List of authors of the programs"),
219 G_TYPE_STRV,
220 G_PARAM_READWRITE));
221 g_object_class_install_property (object_class,
222 PROP_DOCUMENTERS,
223 g_param_spec_boxed ("documenters",
224 gettext_noop("Documenters"),
225 gettext_noop("List of people documenting the program"),
226 G_TYPE_STRV,
227 G_PARAM_READWRITE));
228
229 g_object_class_install_property (object_class,
230 PROP_ARTISTS,
231 g_param_spec_boxed ("artists",
232 gettext_noop("Artists"),
233 gettext_noop("List of people who have contributed artwork to the program"),
234 G_TYPE_STRV,
235 G_PARAM_READWRITE));
236
237 g_object_class_install_property (object_class,
238 PROP_TRANSLATOR_CREDITS,
239 g_param_spec_string ("translator_credits",
240 gettext_noop("Translator credits"),
241 gettext_noop("Credits to the translators. This string should be marked as translatable"),
242 NULL,
243 G_PARAM_READWRITE));
244
245 g_object_class_install_property (object_class,
246 PROP_LOGO,
247 g_param_spec_object ("logo",
248 gettext_noop("Logo"),
249 gettext_noop("A logo for the about box. If this is not set, it defaults to gtk_window_get_default_icon_list()"),
250 GDK_TYPE_PIXBUF,
251 G_PARAM_READWRITE));
252
253 /* Style properties */
254 gtk_widget_class_install_style_property (widget_class,
255 g_param_spec_boxed ("link_color",
256 gettext_noop("Link Color"),
257 gettext_noop("Color of hyperlinks"),
258 GDK_TYPE_COLOR,
259 G_PARAM_READABLE));
260
261 g_type_class_add_private (object_class, sizeof (GtkAboutDialogPrivate));
262}
263
264static void
265gtk_about_dialog_init (GtkAboutDialog *about)
266{
267 GtkAboutDialogPrivate *priv;
268 GtkWidget *vbox, *hbox, *button;
269
270 /* Data */
271 priv = GTK_ABOUT_DIALOG_GET_PRIVATE (about);
272 about->private_data = priv;
273
274 priv->name = NULL;
275 priv->version = NULL;
276 priv->copyright = NULL;
277 priv->comments = NULL;
278 priv->website = NULL;
279 priv->website_label = NULL;
280 priv->translator_credits = NULL;
281 priv->authors = NULL;
282 priv->documenters = NULL;
283 priv->artists = NULL;
284
285 priv->hand_cursor = gdk_cursor_new (GDK_HAND2);
286 priv->regular_cursor = gdk_cursor_new (GDK_XTERM);
287 priv->hovering_over_link = FALSE;
288
289 /* Widgets */
290 gtk_widget_push_composite_child ();
291 vbox = gtk_vbox_new (FALSE, 8);
292 gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
293
294 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about)->vbox), vbox, TRUE, TRUE, 0);
295
296 priv->logo_image = gtk_image_new ();
297 gtk_box_pack_start (GTK_BOX (vbox), priv->logo_image, FALSE, FALSE, 0);
298
299 priv->name_label = gtk_label_new (NULL);
300 gtk_label_set_selectable (GTK_LABEL (priv->name_label), TRUE);
301 gtk_label_set_justify (GTK_LABEL (priv->name_label), GTK_JUSTIFY_CENTER);
302 gtk_box_pack_start (GTK_BOX (vbox), priv->name_label, FALSE, FALSE, 0);
303
304 priv->comments_label = gtk_label_new (NULL);
305 gtk_label_set_selectable (GTK_LABEL (priv->comments_label), TRUE);
306 gtk_label_set_justify (GTK_LABEL (priv->comments_label), GTK_JUSTIFY_CENTER);
307 gtk_label_set_line_wrap (GTK_LABEL (priv->comments_label), TRUE);
308 gtk_box_pack_start (GTK_BOX (vbox), priv->comments_label, FALSE, FALSE, 0);
309
310 priv->copyright_label = gtk_label_new (NULL);
311 gtk_label_set_selectable (GTK_LABEL (priv->copyright_label), TRUE);
312 gtk_label_set_justify (GTK_LABEL (priv->copyright_label), GTK_JUSTIFY_CENTER);
313 gtk_box_pack_start (GTK_BOX (vbox), priv->copyright_label, FALSE, FALSE, 0);
314
315 button = create_link_button (GTK_WIDGET (about), "", "",
316 G_CALLBACK (activate_url), about);
317
318 hbox = gtk_hbox_new (TRUE, 0);
319 gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
320 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);
321 priv->website_button = button;
322
323 gtk_widget_show (vbox);
324 gtk_widget_show (priv->logo_image);
325 gtk_widget_show (priv->name_label);
326 gtk_widget_show (hbox);
327
328 /* Add the OK button */
329 gtk_dialog_add_button (GTK_DIALOG (about), GTK_STOCK_OK, GTK_RESPONSE_OK);
330 gtk_dialog_set_default_response (GTK_DIALOG (about), GTK_RESPONSE_OK);
331
332 /* Add the credits button */
333 button = gtk_button_new_from_stock (gettext_noop("_Credits"));
334 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (about)->action_area),
335 button, FALSE, TRUE, 0);
336 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (about)->action_area), button, TRUE);
337 g_signal_connect (button, "clicked", G_CALLBACK (display_credits_dialog), about);
338 priv->credits_button = button;
339 priv->credits_dialog = NULL;
340
341 /* Add the license button */
342 button = gtk_button_new_from_stock (gettext_noop("_License"));
343 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (about)->action_area),
344 button, FALSE, TRUE, 0);
345 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (about)->action_area), button, TRUE);
346 g_signal_connect (button, "clicked", G_CALLBACK (display_license_dialog), about);
347 priv->license_button = button;
348 priv->license_dialog = NULL;
349
350 gtk_window_set_resizable (GTK_WINDOW (about), FALSE);
351
352 gtk_widget_pop_composite_child ();
353}
354
355static void
356gtk_about_dialog_finalize (GObject *object)
357{
358 GtkAboutDialog *about = GTK_ABOUT_DIALOG (object);
359 GtkAboutDialogPrivate *priv = (GtkAboutDialogPrivate *)about->private_data;
360
361 g_free (priv->name);
362 g_free (priv->version);
363 g_free (priv->copyright);
364 g_free (priv->comments);
365 g_free (priv->license);
366 g_free (priv->website);
367 g_free (priv->website_label);
368 g_free (priv->translator_credits);
369
370 g_strfreev (priv->authors);
371 g_strfreev (priv->documenters);
372 g_strfreev (priv->artists);
373
374 g_free (priv);
375 about->private_data = NULL;
376
377 G_OBJECT_CLASS (gtk_about_dialog_parent_class)->finalize (object);
378}
379
380static void
381gtk_about_dialog_set_property (GObject *object,
382 guint prop_id,
383 const GValue *value,
384 GParamSpec *pspec)
385{
386 GtkAboutDialog *about = GTK_ABOUT_DIALOG (object);
387
388 switch (prop_id)
389 {
390 case PROP_NAME:
391 gtk_about_dialog_set_name (about, g_value_get_string (value));
392 break;
393 case PROP_VERSION:
394 gtk_about_dialog_set_version (about, g_value_get_string (value));
395 break;
396 case PROP_COMMENTS:
397 gtk_about_dialog_set_comments (about, g_value_get_string (value));
398 break;
399 case PROP_WEBSITE:
400 gtk_about_dialog_set_website (about, g_value_get_string (value));
401 break;
402 case PROP_WEBSITE_LABEL:
403 gtk_about_dialog_set_website_label (about, g_value_get_string (value));
404 break;
405 case PROP_LICENSE:
406 gtk_about_dialog_set_license (about, g_value_get_string (value));
407 break;
408 case PROP_COPYRIGHT:
409 gtk_about_dialog_set_copyright (about, g_value_get_string (value));
410 break;
411 case PROP_LOGO:
412 gtk_about_dialog_set_logo (about, g_value_get_object (value));
413 break;
414 case PROP_AUTHORS:
415 gtk_about_dialog_set_authors (about, (gchar**)g_value_get_boxed (value));
416 break;
417 case PROP_DOCUMENTERS:
418 gtk_about_dialog_set_documenters (about, (gchar**)g_value_get_boxed (value));
419 break;
420 case PROP_ARTISTS:
421 gtk_about_dialog_set_artists (about, (gchar**)g_value_get_boxed (value));
422 break;
423 case PROP_TRANSLATOR_CREDITS:
424 gtk_about_dialog_set_translator_credits (about, g_value_get_string (value));
425 break;
426 default:
427 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
428 break;
429 }
430}
431
432static void
433gtk_about_dialog_get_property (GObject *object,
434 guint prop_id,
435 GValue *value,
436 GParamSpec *pspec)
437{
438 GtkAboutDialog *about = GTK_ABOUT_DIALOG (object);
439 GtkAboutDialogPrivate *priv = (GtkAboutDialogPrivate *)about->private_data;
440
441 switch (prop_id)
442 {
443 case PROP_NAME:
444 g_value_set_string (value, priv->name);
445 break;
446 case PROP_VERSION:
447 g_value_set_string (value, priv->version);
448 break;
449 case PROP_COPYRIGHT:
450 g_value_set_string (value, priv->copyright);
451 break;
452 case PROP_COMMENTS:
453 g_value_set_string (value, priv->comments);
454 break;
455 case PROP_WEBSITE:
456 g_value_set_string (value, priv->website);
457 break;
458 case PROP_WEBSITE_LABEL:
459 g_value_set_string (value, priv->website_label);
460 break;
461 case PROP_LICENSE:
462 g_value_set_string (value, priv->license);
463 break;
464 case PROP_TRANSLATOR_CREDITS:
465 g_value_set_string (value, priv->translator_credits);
466 break;
467 case PROP_AUTHORS:
468 g_value_set_boxed (value, priv->authors);
469 break;
470 case PROP_DOCUMENTERS:
471 g_value_set_boxed (value, priv->documenters);
472 break;
473 case PROP_ARTISTS:
474 g_value_set_boxed (value, priv->artists);
475 break;
476 case PROP_LOGO:
477 g_value_set_object (value, gtk_image_get_pixbuf (GTK_IMAGE (priv->logo_image)));
478 break;
479 default:
480 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
481 break;
482 }
483}
484
485/**
486 * gtk_about_dialog_get_name:
487 * @about: a #GtkAboutDialog
488 *
489 * Returns the program name displayed in the about dialog.
490 *
491 * Return value: The program name. The string is owned by the about
492 * dialog and must not be modified.
493 *
494 * Since: 2.6
495 **/
496G_CONST_RETURN gchar *
497gtk_about_dialog_get_name (GtkAboutDialog *about)
498{
499 GtkAboutDialogPrivate *priv;
500
501 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
502
503 priv = (GtkAboutDialogPrivate *)about->private_data;
504
505 return priv->name;
506}
507
508static void
509update_name_version (GtkAboutDialog *about)
510{
511 GtkAboutDialogPrivate *priv;
512 gchar *title_string, *name_string;
513
514 priv = (GtkAboutDialogPrivate *)about->private_data;
515
516 title_string = g_strdup_printf (gettext_noop("About %s"), priv->name);
517 gtk_window_set_title (GTK_WINDOW (about), title_string);
518 g_free (title_string);
519
520 if (priv->version != NULL)
521 name_string = g_markup_printf_escaped ("<span size=\"xx-large\" weight=\"bold\">%s %s</span>",
522 priv->name, priv->version);
523 else
524 name_string = g_markup_printf_escaped ("<span size=\"xx-large\" weight=\"bold\">%s</span>",
525 priv->name);
526
527 gtk_label_set_markup (GTK_LABEL (priv->name_label), name_string);
528
529 g_free (name_string);
530}
531
532/**
533 * gtk_about_dialog_set_name:
534 * @about: a #GtkAboutDialog
535 * @name: the program name
536 *
537 * Sets the name to display in the about dialog.
538 * If this is not set, it defaults to g_get_application_name().
539 *
540 * Since: 2.6
541 **/
542void
543gtk_about_dialog_set_name (GtkAboutDialog *about,
544 const gchar *name)
545{
546 GtkAboutDialogPrivate *priv;
547 gchar *tmp;
548
549 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
550
551 priv = (GtkAboutDialogPrivate *)about->private_data;
552 tmp = priv->name;
553 priv->name = g_strdup (name ? name : g_get_application_name ());
554 g_free (tmp);
555
556 update_name_version (about);
557
558 g_object_notify (G_OBJECT (about), "name");
559}
560
561/**
562 * gtk_about_dialog_get_version:
563 * @about: a #GtkAboutDialog
564 *
565 * Returns the version string.
566 *
567 * Return value: The version string. The string is owned by the about
568 * dialog and must not be modified.
569 *
570 * Since: 2.6
571 **/
572G_CONST_RETURN gchar *
573gtk_about_dialog_get_version (GtkAboutDialog *about)
574{
575 GtkAboutDialogPrivate *priv;
576
577 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
578
579 priv = (GtkAboutDialogPrivate *)about->private_data;
580
581 return priv->version;
582}
583
584/**
585 * gtk_about_dialog_set_version:
586 * @about: a #GtkAboutDialog
587 * @version: the version string
588 *
589 * Sets the version string to display in the about dialog.
590 *
591 * Since: 2.6
592 **/
593void
594gtk_about_dialog_set_version (GtkAboutDialog *about,
595 const gchar *version)
596{
597 GtkAboutDialogPrivate *priv;
598 gchar *tmp;
599
600 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
601
602 priv = (GtkAboutDialogPrivate *)about->private_data;
603
604 tmp = priv->version;
605 priv->version = version ? g_strdup (version) : NULL;
606 g_free (tmp);
607
608 update_name_version (about);
609
610 g_object_notify (G_OBJECT (about), "version");
611}
612
613/**
614 * gtk_about_dialog_get_copyright:
615 * @about: a #GtkAboutDialog
616 *
617 * Returns the copyright string.
618 *
619 * Return value: The copyright string. The string is owned by the about
620 * dialog and must not be modified.
621 *
622 * Since: 2.6
623 **/
624G_CONST_RETURN gchar *
625gtk_about_dialog_get_copyright (GtkAboutDialog *about)
626{
627 GtkAboutDialogPrivate *priv;
628
629 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
630
631 priv = (GtkAboutDialogPrivate *)about->private_data;
632
633 return priv->copyright;
634}
635
636/**
637 * gtk_about_dialog_set_copyright:
638 * @about: a #GtkAboutDialog
639 * @copyright: the copyright string
640 *
641 * Sets the copyright string to display in the about dialog.
642 * This should be a short string of one or two lines.
643 *
644 * Since: 2.6
645 **/
646void
647gtk_about_dialog_set_copyright (GtkAboutDialog *about,
648 const gchar *copyright)
649{
650 GtkAboutDialogPrivate *priv;
651 gchar *copyright_string, *tmp;
652
653 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
654
655 priv = (GtkAboutDialogPrivate *)about->private_data;
656
657 tmp = priv->copyright;
658 priv->copyright = copyright ? g_strdup (copyright) : NULL;
659 g_free (tmp);
660
661 if (priv->copyright != NULL)
662 {
663 copyright_string = g_markup_printf_escaped ("<span size=\"small\">%s</span>",
664 priv->copyright);
665 gtk_label_set_markup (GTK_LABEL (priv->copyright_label), copyright_string);
666 g_free (copyright_string);
667
668 gtk_widget_show (priv->copyright_label);
669 }
670 else
671 gtk_widget_hide (priv->copyright_label);
672
673 g_object_notify (G_OBJECT (about), "copyright");
674}
675
676/**
677 * gtk_about_dialog_get_comments:
678 * @about: a #GtkAboutDialog
679 *
680 * Returns the comments string.
681 *
682 * Return value: The comments. The string is owned by the about
683 * dialog and must not be modified.
684 *
685 * Since: 2.6
686 **/
687G_CONST_RETURN gchar *
688gtk_about_dialog_get_comments (GtkAboutDialog *about)
689{
690 GtkAboutDialogPrivate *priv;
691
692 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
693
694 priv = (GtkAboutDialogPrivate *)about->private_data;
695
696 return priv->comments;
697}
698
699/**
700 * gtk_about_dialog_set_comments:
701 * @about: a #GtkAboutDialog
702 * @comments: a comments string
703 *
704 * Sets the comments string to display in the about
705 * dialog. This should be a short string of one or
706 * two lines.
707 *
708 * Since: 2.6
709 **/
710void
711gtk_about_dialog_set_comments (GtkAboutDialog *about,
712 const gchar *comments)
713{
714 GtkAboutDialogPrivate *priv;
715 gchar *tmp;
716
717 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
718
719 priv = (GtkAboutDialogPrivate *)about->private_data;
720
721 tmp = priv->comments;
722 if (comments)
723 {
724 priv->comments = g_strdup (comments);
725 gtk_label_set_text (GTK_LABEL (priv->comments_label), priv->comments);
726 gtk_widget_show (priv->comments_label);
727 }
728 else
729 {
730 priv->comments = NULL;
731 gtk_widget_hide (priv->comments_label);
732 }
733 g_free (tmp);
734
735 g_object_notify (G_OBJECT (about), "comments");
736}
737
738/**
739 * gtk_about_dialog_get_license:
740 * @about: a #GtkAboutDialog
741 *
742 * Returns the license information.
743 *
744 * Return value: The license information. The string is owned by the about
745 * dialog and must not be modified.
746 *
747 * Since: 2.6
748 **/
749G_CONST_RETURN gchar *
750gtk_about_dialog_get_license (GtkAboutDialog *about)
751{
752 GtkAboutDialogPrivate *priv;
753
754 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
755
756 priv = (GtkAboutDialogPrivate *)about->private_data;
757
758 return priv->license;
759}
760
761/**
762 * gtk_about_dialog_set_license:
763 * @about: a #GtkAboutDialog
764 * @license: the license information or %NULL
765 *
766 * Sets the license information to be displayed in the secondary
767 * license dialog. If @license is %NULL, the license button is
768 * hidden.
769 *
770 * Since: 2.6
771 **/
772void
773gtk_about_dialog_set_license (GtkAboutDialog *about,
774 const gchar *license)
775{
776 GtkAboutDialogPrivate *priv;
777 gchar *tmp;
778
779 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
780
781 priv = (GtkAboutDialogPrivate *)about->private_data;
782
783 tmp = priv->license;
784 if (license)
785 {
786 priv->license = g_strdup (license);
787 gtk_widget_show (priv->license_button);
788 }
789 else
790 {
791 priv->license = NULL;
792 gtk_widget_hide (priv->license_button);
793 }
794 g_free (tmp);
795
796 g_object_notify (G_OBJECT (about), "license");
797}
798
799/**
800 * gtk_about_dialog_get_website:
801 * @about: a #GtkAboutDialog
802 *
803 * Returns the website URL.
804 *
805 * Return value: The website URL. The string is owned by the about
806 * dialog and must not be modified.
807 *
808 * Since: 2.6
809 **/
810G_CONST_RETURN gchar *
811gtk_about_dialog_get_website (GtkAboutDialog *about)
812{
813 GtkAboutDialogPrivate *priv;
814
815 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
816
817 priv = (GtkAboutDialogPrivate *)about->private_data;
818
819 return priv->website;
820}
821
822/**
823 * gtk_about_dialog_set_website:
824 * @about: a #GtkAboutDialog
825 * @website: a URL string starting with "http://"
826 *
827 * Sets the URL to use for the website link.
828 *
829 * Since: 2.6
830 **/
831void
832gtk_about_dialog_set_website (GtkAboutDialog *about,
833 const gchar *website)
834{
835 GtkAboutDialogPrivate *priv;
836 gchar *tmp;
837
838 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
839
840 priv = (GtkAboutDialogPrivate *)about->private_data;
841
842 tmp = priv->website;
843 if (website != NULL)
844 {
845 priv->website = g_strdup (website);
846 if (activate_url_hook != NULL)
847 {
848 g_object_set_data_full (G_OBJECT (priv->website_button),
849 "url", g_strdup (website), g_free);
850 if (priv->website_label == NULL)
851 gtk_about_dialog_set_website_label (about, website);
852 }
853 else
854 {
855 GtkWidget *hbox = priv->website_button->parent;
856 gtk_widget_destroy (priv->website_button);
857 priv->website_button = gtk_label_new (website);
858 gtk_label_set_selectable (GTK_LABEL (priv->website_button), TRUE);
859 gtk_container_add (GTK_CONTAINER (hbox), priv->website_button);
860 gtk_widget_show (priv->website_button);
861 }
862 }
863 else
864 {
865 priv->website = NULL;
866 g_object_set_data (G_OBJECT (priv->website_button), "url", NULL);
867 }
868 g_free (tmp);
869
870 g_object_notify (G_OBJECT (about), "website");
871}
872
873/**
874 * gtk_about_dialog_get_website_label:
875 * @about: a #GtkAboutDialog
876 *
877 * Returns the label used for the website link.
878 *
879 * Return value: The label used for the website link. The string is owned by the about
880 * dialog and must not be modified.
881 *
882 * Since: 2.6
883 **/
884G_CONST_RETURN gchar *
885gtk_about_dialog_get_website_label (GtkAboutDialog *about)
886{
887 GtkAboutDialogPrivate *priv;
888
889 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
890
891 priv = (GtkAboutDialogPrivate *)about->private_data;
892
893 return priv->website_label;
894}
895
896/**
897 * gtk_about_dialog_set_website_label:
898 * @about: a #GtkAboutDialog
899 * @website_label: the label used for the website link
900 *
901 * Sets the label to be used for the website link.
902 * It defaults to the website URL.
903 *
904 * Since: 2.6
905 **/
906void
907gtk_about_dialog_set_website_label (GtkAboutDialog *about,
908 const gchar *website_label)
909{
910 GtkAboutDialogPrivate *priv;
911 gchar *tmp;
912
913 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
914
915 priv = (GtkAboutDialogPrivate *)about->private_data;
916
917 tmp = priv->website_label;
918 if (activate_url_hook != NULL)
919 {
920 if (website_label != NULL)
921 {
922 priv->website_label = g_strdup (website_label);
923 set_link_button_text (GTK_WIDGET (about),
924 priv->website_button,
925 priv->website_label);
926 gtk_widget_show (priv->website_button);
927 }
928 else
929 {
930 priv->website_label = NULL;
931 gtk_widget_hide (priv->website_button);
932 }
933 }
934 g_free (tmp);
935
936 g_object_notify (G_OBJECT (about), "website_label");
937}
938
939/**
940 * gtk_about_dialog_get_authors:
941 * @about: a #GtkAboutDialog
942 *
943 * Returns the string which are displayed in the authors tab
944 * of the secondary credits dialog.
945 *
946 * Return value: A %NULL-terminated string array containing
947 * the authors. The array is owned by the about dialog
948 * and must not be modified.
949 *
950 * Since: 2.6
951 **/
952gchar **
953gtk_about_dialog_get_authors (GtkAboutDialog *about)
954{
955 GtkAboutDialogPrivate *priv;
956
957 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
958
959 priv = (GtkAboutDialogPrivate *)about->private_data;
960
961 return priv->authors;
962}
963
964/**
965 * gtk_about_dialog_set_authors:
966 * @about: a #GtkAboutDialog
967 * @authors: a %NULL-terminated array of strings
968 *
969 * Sets the strings which are displayed in the authors tab
970 * of the secondary credits dialog.
971 *
972 * Since: 2.6
973 **/
974void
975gtk_about_dialog_set_authors (GtkAboutDialog *about,
976 gchar **authors)
977{
978 GtkAboutDialogPrivate *priv;
979 gchar **tmp;
980
981 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
982
983 priv = (GtkAboutDialogPrivate *)about->private_data;
984
985 tmp = priv->authors;
986 priv->authors = g_strdupv (authors);
987 g_strfreev (tmp);
988
989 if (priv->authors != NULL)
990 gtk_widget_show (priv->credits_button);
991
992 g_object_notify (G_OBJECT (about), "authors");
993}
994
995/**
996 * gtk_about_dialog_get_documenters:
997 * @about: a #GtkAboutDialog
998 *
999 * Returns the string which are displayed in the documenters
1000 * tab of the secondary credits dialog.
1001 *
1002 * Return value: A %NULL-terminated string array containing
1003 * the documenters. The array is owned by the about dialog
1004 * and must not be modified.
1005 *
1006 * Since: 2.6
1007 **/
1008gchar **
1009gtk_about_dialog_get_documenters (GtkAboutDialog *about)
1010{
1011 GtkAboutDialogPrivate *priv;
1012
1013 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
1014
1015 priv = (GtkAboutDialogPrivate *)about->private_data;
1016
1017 return priv->documenters;
1018}
1019
1020/**
1021 * gtk_about_dialog_set_documenters:
1022 * @about: a #GtkAboutDialog
1023 * @authors: a %NULL-terminated array of strings
1024 *
1025 * Sets the strings which are displayed in the documenters tab
1026 * of the secondary credits dialog.
1027 *
1028 * Since: 2.6
1029 **/
1030void
1031gtk_about_dialog_set_documenters (GtkAboutDialog *about,
1032 gchar **documenters)
1033{
1034 GtkAboutDialogPrivate *priv;
1035 gchar **tmp;
1036
1037 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
1038
1039 priv = (GtkAboutDialogPrivate *)about->private_data;
1040
1041 tmp = priv->documenters;
1042 priv->documenters = g_strdupv (documenters);
1043 g_strfreev (tmp);
1044
1045 if (priv->documenters != NULL)
1046 gtk_widget_show (priv->credits_button);
1047
1048 g_object_notify (G_OBJECT (about), "documenters");
1049}
1050
1051/**
1052 * gtk_about_dialog_get_artists:
1053 * @about: a #GtkAboutDialog
1054 *
1055 * Returns the string which are displayed in the artists tab
1056 * of the secondary credits dialog.
1057 *
1058 * Return value: A %NULL-terminated string array containing
1059 * the artists. The array is owned by the about dialog
1060 * and must not be modified.
1061 *
1062 * Since: 2.6
1063 **/
1064gchar **
1065gtk_about_dialog_get_artists (GtkAboutDialog *about)
1066{
1067 GtkAboutDialogPrivate *priv;
1068
1069 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
1070
1071 priv = (GtkAboutDialogPrivate *)about->private_data;
1072
1073 return priv->artists;
1074}
1075
1076/**
1077 * gtk_about_dialog_set_artists:
1078 * @about: a #GtkAboutDialog
1079 * @authors: a %NULL-terminated array of strings
1080 *
1081 * Sets the strings which are displayed in the artists tab
1082 * of the secondary credits dialog.
1083 *
1084 * Since: 2.6
1085 **/
1086void
1087gtk_about_dialog_set_artists (GtkAboutDialog *about,
1088 gchar **artists)
1089{
1090 GtkAboutDialogPrivate *priv;
1091 gchar **tmp;
1092
1093 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
1094
1095 priv = (GtkAboutDialogPrivate *)about->private_data;
1096
1097 tmp = priv->artists;
1098 priv->artists = g_strdupv (artists);
1099 g_strfreev (tmp);
1100
1101 if (priv->artists != NULL)
1102 gtk_widget_show (priv->credits_button);
1103
1104 g_object_notify (G_OBJECT (about), "artists");
1105}
1106
1107/**
1108 * gtk_about_dialog_get_translator_credits:
1109 * @about: a #GtkAboutDialog
1110 *
1111 * Returns the translator credits string which is displayed
1112 * in the translators tab of the secondary credits dialog.
1113 *
1114 * Return value: The translator credits string. The string is
1115 * owned by the about dialog and must not be modified.
1116 *
1117 * Since: 2.6
1118 **/
1119G_CONST_RETURN gchar *
1120gtk_about_dialog_get_translator_credits (GtkAboutDialog *about)
1121{
1122 GtkAboutDialogPrivate *priv;
1123
1124 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
1125
1126 priv = (GtkAboutDialogPrivate *)about->private_data;
1127
1128 return priv->translator_credits;
1129}
1130
1131/**
1132 * gtk_about_dialog_set_translator_credits:
1133 * @about: a #GtkAboutDialog
1134 * @translator_credits: the translator credits
1135 *
1136 * Sets the translator credits string which is displayed in
1137 * the translators tab of the secondary credits dialog.
1138 *
1139 * The intended use for this string is to display the translator
1140 * of the language which is currently used in the user interface.
1141 * Using gettext(), a simple way to achieve that is to mark the
1142 * string for translation:
1143 * <informalexample><programlisting>
1144 * gtk_about_dialog_set_translator_credits (about, _("translator-credits"));
1145 * </programlisting></informalexample>
1146 *
1147 * Since: 2.6
1148 **/
1149void
1150gtk_about_dialog_set_translator_credits (GtkAboutDialog *about,
1151 const gchar *translator_credits)
1152{
1153 GtkAboutDialogPrivate *priv;
1154 gchar *tmp;
1155
1156 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
1157
1158 priv = (GtkAboutDialogPrivate *)about->private_data;
1159
1160 tmp = priv->translator_credits;
1161 priv->translator_credits = g_strdup (translator_credits);
1162 g_free (tmp);
1163
1164 if (priv->translator_credits != NULL)
1165 gtk_widget_show (priv->credits_button);
1166
1167 g_object_notify (G_OBJECT (about), "translator-credits");
1168}
1169
1170/**
1171 * gtk_about_dialog_get_logo:
1172 * @about: a #GtkAboutDialog
1173 *
1174 * Returns the pixbuf displayed as logo in the about dialog.
1175 *
1176 * Return value: the pixbuf displayed as logo. The pixbuf is
1177 * owned by the about dialog. If you want to keep a reference
1178 * to it, you have to call g_object_ref() on it.
1179 *
1180 * Since: 2.6
1181 **/
1182GdkPixbuf *
1183gtk_about_dialog_get_logo (GtkAboutDialog *about)
1184{
1185 GtkAboutDialogPrivate *priv;
1186
1187 g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);
1188
1189 priv = (GtkAboutDialogPrivate *)about->private_data;
1190
1191 return gtk_image_get_pixbuf (GTK_IMAGE (priv->logo_image));
1192}
1193
1194static GtkIconSet *
1195icon_set_new_from_pixbufs (GList *pixbufs)
1196{
1197 GtkIconSet *icon_set = gtk_icon_set_new ();
1198
1199 for (; pixbufs; pixbufs = pixbufs->next)
1200 {
1201 GdkPixbuf *pixbuf = GDK_PIXBUF (pixbufs->data);
1202
1203 GtkIconSource *icon_source = gtk_icon_source_new ();
1204 gtk_icon_source_set_pixbuf (icon_source, pixbuf);
1205 gtk_icon_set_add_source (icon_set, icon_source);
1206 }
1207
1208 return icon_set;
1209}
1210
1211/**
1212 * gtk_about_dialog_set_logo:
1213 * @about: a #GtkAboutDialog
1214 * @pixbuf: a #GdkPixbuf, or %NULL
1215 *
1216 * Sets the pixbuf to be displayed as logo in
1217 * the about dialog. If it is %NULL, the default
1218 * window icon set with gtk_window_set_default_icon ()
1219 * will be used.
1220 *
1221 * Since: 2.6
1222 **/
1223void
1224gtk_about_dialog_set_logo (GtkAboutDialog *about,
1225 GdkPixbuf *pixbuf)
1226{
1227 GtkAboutDialogPrivate *priv;
1228
1229 g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
1230
1231 priv = (GtkAboutDialogPrivate *)about->private_data;
1232
1233 if (pixbuf != NULL)
1234 gtk_image_set_from_pixbuf (GTK_IMAGE (priv->logo_image), pixbuf);
1235 else
1236 {
1237 GList *pixbufs = gtk_window_get_default_icon_list ();
1238
1239 if (pixbufs != NULL)
1240 {
1241 GtkIconSet *icon_set = icon_set_new_from_pixbufs (pixbufs);
1242
1243 gtk_image_set_from_icon_set (GTK_IMAGE (priv->logo_image),
1244 icon_set, GTK_ICON_SIZE_DIALOG);
1245
1246 gtk_icon_set_unref (icon_set);
1247 g_list_free (pixbufs);
1248 }
1249 }
1250
1251 g_object_notify (G_OBJECT (about), "logo");
1252}
1253
1254static void
1255activate_url (GtkWidget *widget,
1256 gpointer data)
1257{
1258 GtkAboutDialog *about = GTK_ABOUT_DIALOG (data);
1259 gchar *url = g_object_get_data (G_OBJECT (widget), "url");
1260
1261 if (activate_url_hook != NULL)
1262 (* activate_url_hook) (about, url);
1263}
1264
1265static void
1266set_link_button_text (GtkWidget *about,
1267 GtkWidget *button,
1268 gchar *text)
1269{
1270 GtkWidget *label;
1271 gchar *link;
1272 GdkColor *style_link_color;
1273 GdkColor link_color = { 0, 0, 0, 0xffff };
1274
1275 gtk_widget_ensure_style (about);
1276 gtk_widget_style_get (about, "link_color", &style_link_color, NULL);
1277 if (style_link_color)
1278 {
1279 link_color = *style_link_color;
1280 gdk_color_free (style_link_color);
1281 }
1282
1283 link = g_markup_printf_escaped ("<span foreground=\"#%04x%04x%04x\" underline=\"single\">%s</span>",
1284 link_color.red, link_color.green, link_color.blue, text);
1285
1286 label = gtk_bin_get_child (GTK_BIN (button));
1287 gtk_label_set_markup (GTK_LABEL (label), link);
1288 g_free (link);
1289}
1290
1291static GtkWidget *
1292create_link_button (GtkWidget *about,
1293 gchar *text,
1294 gchar *url,
1295 GCallback callback,
1296 gpointer data)
1297{
1298 GtkWidget *button;
1299
1300 button = gtk_button_new_with_label ("");
1301 GTK_WIDGET_UNSET_FLAGS (button, GTK_RECEIVES_DEFAULT);
1302 gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
1303
1304 g_object_set_data_full (G_OBJECT (button), "url", g_strdup (url), g_free);
1305 set_link_button_text (about, button, text);
1306
1307 g_signal_connect (G_OBJECT (button), "clicked", callback, data);
1308
1309 return button;
1310}
1311
1312static void
1313follow_if_link (GtkAboutDialog *about,
1314 GtkTextIter *iter)
1315{
1316 GSList *tags = NULL, *tagp = NULL;
1317
1318 tags = gtk_text_iter_get_tags (iter);
1319 for (tagp = tags; tagp != NULL; tagp = tagp->next)
1320 {
1321 GtkTextTag *tag = tagp->data;
1322 gchar *email = g_object_get_data (G_OBJECT (tag), "email");
1323 gchar *url = g_object_get_data (G_OBJECT (tag), "url");
1324
1325 if (email != NULL && activate_email_hook != NULL)
1326 {
1327 (* activate_email_hook) (about, email);
1328 break;
1329 }
1330
1331 if (url != NULL && activate_url_hook != NULL)
1332 {
1333 (* activate_url_hook) (about, url);
1334 break;
1335 }
1336 }
1337
1338 if (tags)
1339 g_slist_free (tags);
1340}
1341
1342static gboolean
1343credits_key_press_event (GtkWidget *text_view,
1344 GdkEventKey *event,
1345 GtkAboutDialog *about)
1346{
1347 GtkTextIter iter;
1348 GtkTextBuffer *buffer;
1349
1350 switch (event->keyval)
1351 {
1352 case GDK_Return:
1353 case GDK_KP_Enter:
1354 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
1355 gtk_text_buffer_get_iter_at_mark (buffer, &iter,
1356 gtk_text_buffer_get_insert (buffer));
1357 follow_if_link (about, &iter);
1358 break;
1359
1360 default:
1361 break;
1362 }
1363
1364 return FALSE;
1365}
1366
1367static gboolean
1368credits_event_after (GtkWidget *text_view,
1369 GdkEvent *event,
1370 GtkAboutDialog *about)
1371{
1372 GtkTextIter start, end, iter;
1373 GtkTextBuffer *buffer;
1374 GdkEventButton *button_event;
1375 gint x, y;
1376
1377 if (event->type != GDK_BUTTON_RELEASE)
1378 return FALSE;
1379
1380 button_event = (GdkEventButton *)event;
1381
1382 if (button_event->button != 1)
1383 return FALSE;
1384
1385 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
1386
1387 /* we shouldn't follow a link if the user has selected something */
1388 gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
1389 if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
1390 return FALSE;
1391
1392 gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
1393 GTK_TEXT_WINDOW_WIDGET,
1394 button_event->x, button_event->y, &x, &y);
1395
1396 gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y);
1397
1398 follow_if_link (about, &iter);
1399
1400 return FALSE;
1401}
1402
1403static void
1404set_cursor_if_appropriate (GtkAboutDialog *about,
1405 GtkTextView *text_view,
1406 gint x,
1407 gint y)
1408{
1409 GtkAboutDialogPrivate *priv = (GtkAboutDialogPrivate *)about->private_data;
1410 GSList *tags = NULL, *tagp = NULL;
1411 GtkTextBuffer *buffer;
1412 GtkTextIter iter;
1413 gboolean hovering_over_link = FALSE;
1414
1415 buffer = gtk_text_view_get_buffer (text_view);
1416
1417 gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
1418
1419 tags = gtk_text_iter_get_tags (&iter);
1420 for (tagp = tags; tagp != NULL; tagp = tagp->next)
1421 {
1422 GtkTextTag *tag = tagp->data;
1423 gchar *email = g_object_get_data (G_OBJECT (tag), "email");
1424 gchar *url = g_object_get_data (G_OBJECT (tag), "url");
1425
1426 if (email != NULL || url != NULL)
1427 {
1428 hovering_over_link = TRUE;
1429 break;
1430 }
1431 }
1432
1433 if (hovering_over_link != priv->hovering_over_link)
1434 {
1435 priv->hovering_over_link = hovering_over_link;
1436
1437 if (hovering_over_link)
1438 gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), priv->hand_cursor);
1439 else
1440 gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), priv->regular_cursor);
1441 }
1442
1443 if (tags)
1444 g_slist_free (tags);
1445}
1446
1447static gboolean
1448credits_motion_notify_event (GtkWidget *text_view,
1449 GdkEventMotion *event,
1450 GtkAboutDialog *about)
1451{
1452 gint x, y;
1453
1454 gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
1455 GTK_TEXT_WINDOW_WIDGET,
1456 event->x, event->y, &x, &y);
1457
1458 set_cursor_if_appropriate (about, GTK_TEXT_VIEW (text_view), x, y);
1459
1460 gdk_window_get_pointer (text_view->window, NULL, NULL, NULL);
1461
1462 return FALSE;
1463}
1464
1465
1466static gboolean
1467credits_visibility_notify_event (GtkWidget *text_view,
1468 GdkEventVisibility *event,
1469 GtkAboutDialog *about)
1470{
1471 gint wx, wy, bx, by;
1472
1473 gdk_window_get_pointer (text_view->window, &wx, &wy, NULL);
1474
1475 gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
1476 GTK_TEXT_WINDOW_WIDGET,
1477 wx, wy, &bx, &by);
1478
1479 set_cursor_if_appropriate (about, GTK_TEXT_VIEW (text_view), bx, by);
1480
1481 return FALSE;
1482}
1483
1484static void
1485add_credits_page (GtkAboutDialog *about,
1486 GtkWidget *notebook,
1487 gchar *title,
1488 gchar **people)
1489{
1490 gchar **p;
1491 gchar *q0, *q1, *q2, *r1, *r2;
1492 GtkWidget *sw, *view;
1493 GtkTextBuffer *buffer;
1494 GtkStyle *style;
1495 gboolean linkify_email, linkify_urls;
1496 GdkColor *style_link_color;
1497 GdkColor link_color = { 0, 0, 0, 0xffff };
1498
1499 linkify_email = (activate_email_hook != NULL);
1500 linkify_urls = (activate_url_hook != NULL);
1501
1502 gtk_widget_ensure_style (GTK_WIDGET (about));
1503 gtk_widget_style_get (GTK_WIDGET (about), "link_color", &style_link_color, NULL);
1504 if (style_link_color)
1505 {
1506 link_color = *style_link_color;
1507 gdk_color_free (style_link_color);
1508 }
1509
1510 view = gtk_text_view_new ();
1511 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
1512 gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
1513 gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
1514 gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 8);
1515 gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 8);
1516
1517 g_signal_connect (G_OBJECT (view), "key-press-event",
1518 G_CALLBACK (credits_key_press_event), about);
1519 g_signal_connect (G_OBJECT (view), "event-after",
1520 G_CALLBACK (credits_event_after), about);
1521 g_signal_connect (G_OBJECT (view), "motion-notify-event",
1522 G_CALLBACK (credits_motion_notify_event), about);
1523 g_signal_connect (G_OBJECT (view), "visibility-notify-event",
1524 G_CALLBACK (credits_visibility_notify_event), about);
1525
1526 style = gtk_widget_get_style (view);
1527 gtk_widget_modify_base (view, GTK_STATE_NORMAL,
1528 &style->base[GTK_STATE_INSENSITIVE]);
1529
1530 sw = gtk_scrolled_window_new (NULL, NULL);
1531 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
1532 GTK_POLICY_AUTOMATIC,
1533 GTK_POLICY_AUTOMATIC);
1534 gtk_container_add (GTK_CONTAINER (sw), view);
1535
1536 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1537 sw, gtk_label_new (title));
1538
1539 if (people == NULL)
1540 {
1541 gtk_widget_hide (view);
1542 return;
1543 }
1544 else
1545 gtk_widget_show (view);
1546
1547 for (p = people; *p; p++)
1548 {
1549 q0 = *p;
1550 while (*q0)
1551 {
1552 q1 = linkify_email ? strchr (q0, '<') : NULL;
1553 q2 = q1 ? strchr (q1, '>') : NULL;
1554 r1 = linkify_urls ? strstr (q0, "http://") : NULL;
1555 r2 = r1 ? (strpbrk (r1, " \n\t") ? : strchr (r1, '\0')) : NULL;
1556
1557 if (r1 && r2 && (!q1 || !q2 || (r1 < q1)))
1558 {
1559 q1 = r1;
1560 q2 = r2;
1561 }
1562
1563 if (q1 && q2)
1564 {
1565 GtkTextIter end;
1566 gchar *link;
1567 gchar *link_type;
1568 GtkTextTag *tag;
1569
1570 gtk_text_buffer_insert_at_cursor (buffer, q0, q1 - q0);
1571 gtk_text_buffer_get_end_iter (buffer, &end);
1572
1573 q0 = q2;
1574
1575 if (*q1 == '<')
1576 {
1577 q1++;
1578 q0++;
1579 link_type = "email";
1580 }
1581 else
1582 link_type = "url";
1583
1584 link = g_strndup (q1, q2 - q1);
1585 tag = gtk_text_buffer_create_tag (buffer, NULL,
1586 "foreground_gdk", &link_color,
1587 "underline", PANGO_UNDERLINE_SINGLE,
1588 NULL);
1589 g_object_set_data_full (G_OBJECT (tag), link_type, g_strdup (link), g_free);
1590 gtk_text_buffer_insert_with_tags (buffer, &end, link, -1, tag, NULL);
1591
1592 g_free (link);
1593 }
1594 else
1595 {
1596 gtk_text_buffer_insert_at_cursor (buffer, q0, -1);
1597 break;
1598 }
1599 }
1600
1601 if (p[1])
1602 gtk_text_buffer_insert_at_cursor (buffer, "\n", 1);
1603 }
1604}
1605
1606static void
1607display_credits_dialog (GtkWidget *button,
1608 gpointer data)
1609{
1610 GtkAboutDialog *about = (GtkAboutDialog *)data;
1611 GtkAboutDialogPrivate *priv = (GtkAboutDialogPrivate *)about->private_data;
1612 GtkWidget *dialog, *notebook;
1613
1614 if (priv->credits_dialog != NULL)
1615 {
1616 gtk_window_present (GTK_WINDOW (priv->credits_dialog));
1617 return;
1618 }
1619
1620 dialog = gtk_dialog_new_with_buttons (gettext_noop("Credits"),
1621 GTK_WINDOW (about),
1622 GTK_DIALOG_DESTROY_WITH_PARENT,
1623 GTK_STOCK_OK, GTK_RESPONSE_OK,
1624 NULL);
1625 priv->credits_dialog = dialog;
1626 gtk_window_set_default_size (GTK_WINDOW (dialog), 360, 260);
1627 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
1628
1629 gtk_window_set_modal (GTK_WINDOW (dialog),
1630 gtk_window_get_modal (GTK_WINDOW (about)));
1631
1632 g_signal_connect (dialog, "response",
1633 G_CALLBACK (gtk_widget_destroy), dialog);
1634 g_signal_connect (dialog, "destroy",
1635 G_CALLBACK (gtk_widget_destroyed),
1636 &(priv->credits_dialog));
1637
1638 notebook = gtk_notebook_new ();
1639 gtk_container_set_border_width (GTK_CONTAINER (notebook), 8);
1640 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), notebook, TRUE, TRUE, 0);
1641
1642 if (priv->authors != NULL)
1643 add_credits_page (about, notebook, gettext_noop("Written by"), priv->authors);
1644
1645 if (priv->documenters != NULL)
1646 add_credits_page (about, notebook, gettext_noop("Documented by"), priv->documenters);
1647
1648 if (priv->translator_credits != NULL)
1649 {
1650 gchar *translators[2];
1651
1652 translators[0] = priv->translator_credits;
1653 translators[1] = NULL;
1654
1655 add_credits_page (about, notebook, gettext_noop("Translated by"), translators);
1656 }
1657
1658 if (priv->artists != NULL)
1659 add_credits_page (about, notebook, gettext_noop("Artwork by"), priv->artists);
1660
1661 gtk_widget_show_all (dialog);
1662}
1663
1664static void
1665display_license_dialog (GtkWidget *button,
1666 gpointer data)
1667{
1668 GtkAboutDialog *about = (GtkAboutDialog *)data;
1669 GtkAboutDialogPrivate *priv = (GtkAboutDialogPrivate *)about->private_data;
1670 GtkWidget *dialog, *view, *sw;
1671
1672 if (priv->license_dialog != NULL)
1673 {
1674 gtk_window_present (GTK_WINDOW (priv->license_dialog));
1675 return;
1676 }
1677
1678 dialog = gtk_dialog_new_with_buttons (gettext_noop("License"),
1679 GTK_WINDOW (about),
1680 GTK_DIALOG_DESTROY_WITH_PARENT,
1681 GTK_STOCK_OK, GTK_RESPONSE_OK,
1682 NULL);
1683 priv->license_dialog = dialog;
1684 gtk_window_set_default_size (GTK_WINDOW (dialog), 420, 320);
1685 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
1686
1687 gtk_window_set_modal (GTK_WINDOW (dialog),
1688 gtk_window_get_modal (GTK_WINDOW (about)));
1689
1690 g_signal_connect (dialog, "response",
1691 G_CALLBACK (gtk_widget_destroy), dialog);
1692 g_signal_connect (dialog, "destroy",
1693 G_CALLBACK (gtk_widget_destroyed),
1694 &(priv->license_dialog));
1695
1696 sw = gtk_scrolled_window_new (NULL, NULL);
1697 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
1698 GTK_POLICY_AUTOMATIC,
1699 GTK_POLICY_AUTOMATIC);
1700 gtk_container_set_border_width (GTK_CONTAINER (sw), 8);
1701 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), sw, TRUE, TRUE, 0);
1702
1703 view = gtk_text_view_new ();
1704 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
1705 priv->license, -1);
1706
1707 gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
1708 gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
1709 gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 8);
1710 gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 8);
1711
1712 gtk_container_add (GTK_CONTAINER (sw), view);
1713
1714 gtk_widget_show_all (dialog);
1715}
1716
1717/**
1718 * gtk_about_dialog_new:
1719 *
1720 * Creates a new #GtkAboutDialog.
1721 *
1722 * Returns: a newly created #GtkAboutDialog
1723 *
1724 * Since: 2.6
1725 */
1726GtkWidget *
1727gtk_about_dialog_new (void)
1728{
1729 GtkAboutDialog *dialog = GTK_ABOUT_DIALOG (g_object_new (GTK_TYPE_ABOUT_DIALOG, NULL));
1730
1731 /* force defaults */
1732 gtk_about_dialog_set_name (dialog, NULL);
1733 gtk_about_dialog_set_logo (dialog, NULL);
1734
1735 /* Close dialog on user response */
1736 g_signal_connect (G_OBJECT (dialog),
1737 "response",
1738 G_CALLBACK (gtk_widget_hide),
1739 NULL);
1740
1741 return GTK_WIDGET (dialog);
1742}
1743
1744/**
1745 * gtk_about_dialog_set_email_hook:
1746 * @func: a function to call when an email link is activated.
1747 *
1748 * Installs a global function to be called whenever the user activates an
1749 * email link in an about dialog.
1750 *
1751 * Return value: the previous email hook.
1752 *
1753 * Since: 2.6
1754 */
1755GtkAboutDialogActivateLinkFunc
1756gtk_about_dialog_set_email_hook (GtkAboutDialogActivateLinkFunc func)
1757{
1758 GtkAboutDialogActivateLinkFunc old;
1759
1760 old = activate_email_hook;
1761
1762 activate_email_hook = func;
1763
1764 return old;
1765}
1766
1767/**
1768 * gtk_about_dialog_set_email_hook:
1769 * @func: a function to call when a URL link is activated.
1770 *
1771 * Installs a global function to be called whenever the user activates a
1772 * URL link in an about dialog.
1773 *
1774 * Return value: the previous URL hook.
1775 *
1776 * Since: 2.6
1777 */
1778GtkAboutDialogActivateLinkFunc
1779gtk_about_dialog_set_url_hook (GtkAboutDialogActivateLinkFunc func)
1780{
1781 GtkAboutDialogActivateLinkFunc old;
1782
1783 old = activate_url_hook;
1784
1785 activate_url_hook = func;
1786
1787 return old;
1788}
1789
1790/**
1791 * gtk_show_about_dialog:
1792 * @parent: transient parent, or %NULL for none
1793 * @first_property_name: the name of the first property
1794 * @Varargs: value of first property, followed by more properties, %NULL-terminated
1795 *
1796 * This is a convenience function for showing an application's about box.
1797 *
1798 * Since: 2.6
1799 */
1800void
1801gtk_show_about_dialog (GtkWindow *parent,
1802 const gchar *first_property_name,
1803 ...)
1804{
1805 static GtkWidget *global_about_dialog = NULL;
1806 GtkWidget *dialog = NULL;
1807 va_list var_args;
1808
1809 if (parent)
1810 dialog = g_object_get_data (G_OBJECT (parent), "gtk-about-dialog");
1811 else
1812 dialog = global_about_dialog;
1813
1814 if (!dialog)
1815 {
1816 dialog = gtk_about_dialog_new ();
1817
1818 g_object_ref (G_OBJECT (dialog));
1819 gtk_object_sink (GTK_OBJECT (dialog));
1820
1821 g_signal_connect (dialog, "delete_event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
1822
1823 va_start (var_args, first_property_name);
1824 g_object_set_valist (G_OBJECT (dialog), first_property_name, var_args);
1825 va_end (var_args);
1826
1827 if (parent)
1828 {
1829 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
1830 g_object_set_data_full (G_OBJECT (parent), "gtk-about-dialog",
1831 dialog, g_object_unref);
1832 }
1833 else
1834 global_about_dialog = dialog;
1835
1836 }
1837
1838 gtk_window_present (GTK_WINDOW (dialog));
1839}
1840
1841
1842
1843
1844
1845
1846
diff --git a/src/gtk26about.h b/src/gtk26about.h
new file mode 100644
index 00000000..1f986302
--- /dev/null
+++ b/src/gtk26about.h
@@ -0,0 +1,117 @@
1/* This code was copied from GTK (2.6/CVS).
2
3 GTK - The GIMP Toolkit
4
5 Copyright (C) 2001 CodeFactory AB
6 Copyright (C) 2001 Anders Carlsson <andersca@codefactory.se>
7 Copyright (C) 2003, 2004 Matthias Clasen <mclasen@redhat.com>
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Library General Public
20 License along with the Gnome Library; see the file COPYING.LIB. If not,
21 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
23
24 Author: Anders Carlsson <andersca@codefactory.se>
25
26*/
27
28#ifndef __GTK_ABOUT_DIALOG_H__
29#define __GTK_ABOUT_DIALOG_H__
30
31#include <gtk/gtkdialog.h>
32
33G_BEGIN_DECLS
34
35#define GTK_TYPE_ABOUT_DIALOG (gtk_about_dialog_get_type ())
36#define GTK_ABOUT_DIALOG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_ABOUT_DIALOG, GtkAboutDialog))
37#define GTK_ABOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ABOUT_DIALOG, GtkAboutDialogClass))
38#define GTK_IS_ABOUT_DIALOG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_ABOUT_DIALOG))
39#define GTK_IS_ABOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ABOUT_DIALOG))
40#define GTK_ABOUT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ABOUT_DIALOG, GtkAboutDialogClass))
41
42typedef struct _GtkAboutDialog GtkAboutDialog;
43typedef struct _GtkAboutDialogClass GtkAboutDialogClass;
44
45struct _GtkAboutDialog
46{
47 GtkDialog parent_instance;
48
49 /*< private >*/
50 gpointer private_data;
51};
52
53struct _GtkAboutDialogClass
54{
55 GtkDialogClass parent_class;
56
57 /* Padding for future expansion */
58 void (*_gtk_reserved1) (void);
59 void (*_gtk_reserved2) (void);
60 void (*_gtk_reserved3) (void);
61 void (*_gtk_reserved4) (void);
62};
63
64GType gtk_about_dialog_get_type (void) G_GNUC_CONST;
65GtkWidget *gtk_about_dialog_new (void);
66void gtk_show_about_dialog (GtkWindow *parent,
67 const gchar *first_property_name,
68 ...);
69
70G_CONST_RETURN gchar *gtk_about_dialog_get_name (GtkAboutDialog *about);
71void gtk_about_dialog_set_name (GtkAboutDialog *about,
72 const gchar *name);
73G_CONST_RETURN gchar *gtk_about_dialog_get_version (GtkAboutDialog *about);
74void gtk_about_dialog_set_version (GtkAboutDialog *about,
75 const gchar *version);
76G_CONST_RETURN gchar *gtk_about_dialog_get_copyright (GtkAboutDialog *about);
77void gtk_about_dialog_set_copyright (GtkAboutDialog *about,
78 const gchar *copyright);
79G_CONST_RETURN gchar *gtk_about_dialog_get_comments (GtkAboutDialog *about);
80void gtk_about_dialog_set_comments (GtkAboutDialog *about,
81 const gchar *comments);
82G_CONST_RETURN gchar *gtk_about_dialog_get_license (GtkAboutDialog *about);
83void gtk_about_dialog_set_license (GtkAboutDialog *about,
84 const gchar *license);
85G_CONST_RETURN gchar *gtk_about_dialog_get_website (GtkAboutDialog *about);
86void gtk_about_dialog_set_website (GtkAboutDialog *about,
87 const gchar *website);
88G_CONST_RETURN gchar *gtk_about_dialog_get_website_label (GtkAboutDialog *about);
89void gtk_about_dialog_set_website_label (GtkAboutDialog *about,
90 const gchar *website_label);
91gchar **gtk_about_dialog_get_authors (GtkAboutDialog *about);
92void gtk_about_dialog_set_authors (GtkAboutDialog *about,
93 gchar **authors);
94gchar **gtk_about_dialog_get_documenters (GtkAboutDialog *about);
95void gtk_about_dialog_set_documenters (GtkAboutDialog *about,
96 gchar **documenters);
97gchar ** gtk_about_dialog_get_artists (GtkAboutDialog *about);
98void gtk_about_dialog_set_artists (GtkAboutDialog *about,
99 gchar **artists);
100G_CONST_RETURN gchar *gtk_about_dialog_get_translator_credits (GtkAboutDialog *about);
101void gtk_about_dialog_set_translator_credits (GtkAboutDialog *about,
102 const gchar *translator_credits);
103GdkPixbuf *gtk_about_dialog_get_logo (GtkAboutDialog *about);
104void gtk_about_dialog_set_logo (GtkAboutDialog *about,
105 GdkPixbuf *logo);
106
107typedef void (* GtkAboutDialogActivateLinkFunc) (GtkAboutDialog *about,
108 const gchar *link);
109
110GtkAboutDialogActivateLinkFunc gtk_about_dialog_set_email_hook (GtkAboutDialogActivateLinkFunc func);
111GtkAboutDialogActivateLinkFunc gtk_about_dialog_set_url_hook (GtkAboutDialogActivateLinkFunc func);
112
113G_END_DECLS
114
115#endif /* __GTK_ABOUT_DIALOG_H__ */
116
117
diff --git a/src/helper.c b/src/helper.c
new file mode 100644
index 00000000..c15b93e5
--- /dev/null
+++ b/src/helper.c
@@ -0,0 +1,498 @@
1/*
2 This file is part of GNUnet
3
4 GNUnet is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published
6 by the Free Software Foundation; either version 2, or (at your
7 option) any later version.
8
9 GNUnet is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNUnet; see the file COPYING. If not, write to the
16 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19/**
20 * @file src/applications/afs/gtkui/helper.c
21 * @brief This file contains some GUI helper functions
22 * @author Igor Wronsky
23 */
24
25#include "platform.h"
26#include "helper.h"
27#include <stdlib.h>
28#ifndef MINGW
29 #include <sys/wait.h>
30#endif
31#include "main.h"
32
33#define HELPER_DEBUG NO
34
35GtkWidget * infoWindow = NULL;
36
37static GtkWidget * infoText = NULL;
38
39/* the main thread */
40static PTHREAD_T mainThread;
41
42static SaveCall ** psc;
43static unsigned int pscCount;
44static Mutex sclock;
45
46/**
47 * Call a callback function from the mainloop/main thread ("SaveCall").
48 * Since GTK doesn't work with multi-threaded applications under Windows,
49 * all GTK operations have to be done in the main thread
50 */
51void gtkSaveCall(GtkFunction func, void *args) {
52 SaveCall call;
53 int i;
54
55 call.args = args;
56 call.func = func;
57 MUTEX_LOCK(&sclock);
58 if (! PTHREAD_SELF_TEST(&mainThread)) {
59 call.sem = SEMAPHORE_NEW(0);
60 GROW(psc,
61 pscCount,
62 pscCount+1);
63 psc[pscCount-1] = &call;
64 MUTEX_UNLOCK(&sclock);
65 gtk_idle_add(func, &call);
66 SEMAPHORE_DOWN(call.sem);
67 /* remove from psc list */
68 MUTEX_LOCK(&sclock);
69 for (i=0;i<pscCount;i++)
70 if (psc[i] == &call) {
71 psc[i] = psc[pscCount-1];
72 break;
73 }
74 GNUNET_ASSERT(i != pscCount);
75 GROW(psc,
76 pscCount,
77 pscCount-1);
78 MUTEX_UNLOCK(&sclock);
79 SEMAPHORE_FREE(call.sem);
80 } else {
81 MUTEX_UNLOCK(&sclock);
82 call.sem = NULL;
83 func(&call);
84 }
85}
86
87/**
88 * Initialize "SaveCalls"
89 */
90void gtkInitSaveCalls() {
91 MUTEX_CREATE_RECURSIVE(&sclock);
92 PTHREAD_GET_SELF(&mainThread);
93}
94
95int gtkRunSomeSaveCalls() {
96 int i;
97
98 if (! PTHREAD_SELF_TEST(&mainThread))
99 return NO;
100 MUTEX_LOCK(&sclock);
101 if (pscCount == 0) {
102 MUTEX_UNLOCK(&sclock);
103 return NO;
104 }
105 i = randomi(pscCount);
106 if (TRUE == g_idle_remove_by_data(psc[i]))
107 psc[i]->func(psc[i]);
108 MUTEX_UNLOCK(&sclock);
109 gnunet_util_sleep(50 * cronMILLIS);
110 /* sleep here is somewhat important, first of
111 all, after completion we need to give the
112 semaphore-mechanism time to remove the save-call
113 from the list to avoid running it twice;
114 also, this function might be called in a tight
115 loop (see search.c), so we should give the
116 other threads some time to run. */
117
118 return YES;
119}
120
121void gtkDoneSaveCalls() {
122 int i;
123 PTHREAD_REL_SELF(&mainThread);
124 MUTEX_LOCK(&sclock);
125 for (i=0;i<pscCount;i++)
126 psc[i]->func(psc[i]);
127 i = pscCount;
128 MUTEX_UNLOCK(&sclock);
129 /* wait until all PSC-jobs have left
130 the gtkSaveCall method before destroying
131 the mutex! */
132 while (i != 0) {
133 gnunet_util_sleep(50 * cronMILLIS);
134 MUTEX_LOCK(&sclock);
135 i = pscCount;
136 MUTEX_UNLOCK(&sclock);
137 }
138 MUTEX_DESTROY(&sclock);
139}
140
141
142/**
143 * Called from a "SaveCall"-function to indicate that it is done
144 */
145void gtkSaveCallDone(Semaphore *sem) {
146 if (sem)
147 SEMAPHORE_UP(sem);
148}
149
150/**
151 * Destroy a widget. Called from threads other than the main thread
152 */
153gint doDestroyWidget(SaveCall *call) {
154 gtk_widget_destroy((GtkWidget *) call->args);
155
156 gtkSaveCallDone(call->sem);
157
158 return FALSE;
159}
160
161/**
162 * Callback for handling "delete_event": close the window
163 */
164gint deleteEvent(GtkWidget * widget,
165 GdkEvent * event,
166 gpointer data) {
167#if DEBUG_HELPER
168 LOG(LOG_DEBUG,
169 "In '%s'.\n",
170 __FUNCTION__);
171#endif
172 return FALSE;
173}
174
175/**
176 * A callback to destroy any widget given as second argument
177 */
178void destroyWidget(GtkWidget * dummy,
179 GtkWidget * widget) {
180#if DEBUG_HELPER
181 LOG(LOG_DEBUG,
182 "In '%s' of %p.\n",
183 __FUNCTION__,
184 widget);
185#endif
186 gtk_widget_destroy(widget);
187}
188
189/**
190 * Callback function for guiMessage()
191 */
192gint doGuiMessage(SaveCall *call) {
193 GtkWidget * window;
194 GtkWidget * label;
195 GtkWidget * box;
196 GtkWidget * button;
197
198 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
199 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
200 gtk_window_set_title(GTK_WINDOW(window),
201 _("Notification"));
202 gtk_signal_connect(GTK_OBJECT(window),
203 "delete_event",
204 GTK_SIGNAL_FUNC(deleteEvent),
205 NULL);
206
207 box = gtk_vbox_new(FALSE, 0);
208 gtk_container_add(GTK_CONTAINER(window),
209 box);
210
211 label = gtk_label_new((gchar *) call->args);
212 free((gchar *) call->args); /* allocated in g_strdup_vprintf */
213 gtk_box_pack_start(GTK_BOX(box),
214 label,
215 FALSE,
216 FALSE,
217 0);
218
219 button = gtk_button_new_with_label(_("Ok"));
220 gtk_signal_connect(GTK_OBJECT (button),
221 "clicked",
222 GTK_SIGNAL_FUNC(destroyWidget),
223 window);
224 gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,0);
225
226 gtk_window_set_position(GTK_WINDOW(window),
227 GTK_WIN_POS_MOUSE);
228 gtk_widget_show_all(window);
229 gtk_widget_grab_focus(button);
230
231 gtkSaveCallDone(call->sem);
232
233 return FALSE;
234}
235
236/**
237 * Displays an informative message to the user in a fresh window
238 */
239void guiMessage(const char * format, ...) {
240 va_list args;
241 gchar *note;
242
243 va_start(args, format);
244 note = g_strdup_vprintf(format, args);
245 va_end(args);
246
247 gtkSaveCall((GtkFunction) doGuiMessage, note);
248}
249
250static void hideWindow(GtkWidget * widget,
251 gpointer data) {
252 if(widget)
253 gtk_widget_hide(widget);
254}
255
256/**
257 * Callback for infoMessage()
258 */
259gint doInfoMessage(SaveCall *call) {
260 GtkTextIter iter;
261 GtkTextBuffer * buffer;
262
263 if(!infoWindow) {
264 GtkWidget * box1;
265 GtkWidget * button;
266 GtkWidget * scrolled_window;
267
268 infoWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
269 gtk_signal_connect(GTK_OBJECT(infoWindow),
270 "delete_event",
271 GTK_SIGNAL_FUNC(deleteEvent),
272 NULL);
273
274 gtk_window_set_title(GTK_WINDOW(infoWindow),
275 _("Messages"));
276 gtk_widget_set_usize(GTK_WIDGET(infoWindow),
277 780,
278 300);
279
280 box1 = gtk_vbox_new(FALSE, 0);
281 gtk_container_add(GTK_CONTAINER (infoWindow),
282 box1);
283 gtk_widget_show(box1);
284
285 /* create a scrollable window */
286 scrolled_window = gtk_scrolled_window_new(NULL, NULL);
287 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
288 GTK_POLICY_AUTOMATIC,
289 GTK_POLICY_ALWAYS);
290 gtk_box_pack_start(GTK_BOX(box1),
291 scrolled_window,
292 TRUE,
293 TRUE,
294 0);
295 gtk_widget_show(scrolled_window);
296
297 /* create a text widget */
298 infoText = gtk_text_view_new();
299
300 gtk_text_view_set_editable(GTK_TEXT_VIEW (infoText),
301 FALSE);
302 gtk_container_add(GTK_CONTAINER(scrolled_window),
303 infoText);
304 gtk_widget_show(infoText);
305 gtk_widget_realize(infoText);
306
307 /* finish with a close button */
308 button = gtk_button_new_with_label(_("Close"));
309 gtk_box_pack_start(GTK_BOX (box1),
310 button,
311 FALSE,
312 FALSE,
313 0);
314 gtk_signal_connect_object(GTK_OBJECT(button),
315 "clicked",
316 GTK_SIGNAL_FUNC(hideWindow),
317 GTK_OBJECT(infoWindow));
318 gtk_signal_connect_object(GTK_OBJECT(infoWindow),
319 "delete_event",
320 GTK_SIGNAL_FUNC(hideWindow),
321 GTK_OBJECT(infoWindow));
322 gtk_signal_connect_object(GTK_OBJECT(infoWindow),
323 "destroy",
324 GTK_SIGNAL_FUNC(hideWindow),
325 GTK_OBJECT(infoWindow));
326 gtk_widget_show(button);
327 }
328 if(((InfoMessage *) call->args)->doPopup==YES)
329 gtk_widget_show(infoWindow);
330
331 /* append the text */
332 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW (infoText));
333 gtk_text_buffer_get_iter_at_offset(buffer, &iter, -1);
334 gtk_text_buffer_insert(buffer,
335 &iter,
336 ((InfoMessage *) call->args)->note,
337 -1);
338
339 gtkSaveCallDone(call->sem);
340
341 return FALSE;
342}
343
344/**
345 * Appends a message to the info window
346 *
347 * @param doPopup do we open the window, YES or NO
348 *
349 */
350void infoMessage(int doPopup, const char * format, ...) {
351 va_list args;
352 InfoMessage info;
353
354 va_start(args, format);
355 info.note = g_strdup_vprintf(format, args);
356 va_end(args);
357 info.doPopup = doPopup;
358 gtkSaveCall((GtkFunction) doInfoMessage, &info);
359 g_free(info.note);
360}
361
362/**
363 * Appends a log entry to the info window
364 *
365 * @param txt the log entry
366 *
367 */
368void addLogEntry(const char *txt) {
369 static GtkWidget * s = NULL;
370 static int once = 1;
371 static guint id;
372
373 if (once) {
374 once = 0;
375 s = glade_xml_get_widget(mainXML,
376 "statusbar");
377 id = gtk_statusbar_get_context_id(GTK_STATUSBAR(s),
378 "LOG");
379 } else
380 gtk_statusbar_pop(GTK_STATUSBAR(s),
381 id);
382 gtk_statusbar_push(GTK_STATUSBAR(s),
383 id,
384 txt);
385 infoMessage(NO, txt);
386}
387
388GtkNotebook * notebook = NULL;
389
390gint doAddToNotebook(SaveCall *call) {
391 GtkWidget * label = gtk_label_new(((AddNotebook *) call->args)->labelName);
392 gtk_notebook_append_page(notebook,
393 ((AddNotebook *) call->args)->frame,
394 label);
395 gtk_widget_show(((AddNotebook *) call->args)->frame);
396
397 gtkSaveCallDone(call->sem);
398
399 return FALSE;
400}
401
402void addToNotebook(const char * labelName,
403 GtkWidget * frame) {
404 AddNotebook note;
405
406 note.labelName = labelName;
407 note.frame = frame;
408 /* add a new notebook for the search results */
409 gtkSaveCall((GtkFunction) doAddToNotebook, &note);
410}
411
412/**
413 * A function for numeric comparisons of strings
414 */
415gint numericComp(GtkCList *clist,
416 gconstpointer ptr1,
417 gconstpointer ptr2) {
418 double value1;
419 double value2;
420 GtkCListRow * row1 = (GtkCListRow *) ptr1;
421 GtkCListRow * row2 = (GtkCListRow *) ptr2;
422
423 value1 = atof(GTK_CELL_TEXT(row1->cell[clist->sort_column])->text);
424 value2 = atof(GTK_CELL_TEXT(row2->cell[clist->sort_column])->text);
425
426 if(value1>value2)
427 return(-1);
428 else if(value1==value2)
429 return(0);
430 else
431 return(1);
432}
433
434/**
435 * A function for case-insensitive text comparisons
436 */
437gint alphaComp(GtkCList *clist,
438 gconstpointer ptr1,
439 gconstpointer ptr2) {
440 char * text1;
441 char * text2;
442 GtkCListRow * row1 = (GtkCListRow *) ptr1;
443 GtkCListRow * row2 = (GtkCListRow *) ptr2;
444
445 text1 = GTK_CELL_TEXT(row1->cell[clist->sort_column])->text;
446 text2 = GTK_CELL_TEXT(row2->cell[clist->sort_column])->text;
447
448 return (strcasecmp(text1,text2));
449}
450
451/**
452 * A function for percentage comparisons
453 */
454gint percentComp(GtkCList *clist,
455 gconstpointer ptr1,
456 gconstpointer ptr2) {
457 char * tmp1;
458 char * tmp2;
459 double value1;
460 double value2;
461 GtkCListRow * row1 = (GtkCListRow *) ptr1;
462 GtkCListRow * row2 = (GtkCListRow *) ptr2;
463
464 tmp1 = GTK_CELL_TEXT(row1->cell[clist->sort_column])->text;
465 tmp2 = GTK_CELL_TEXT(row2->cell[clist->sort_column])->text;
466
467 /* Hack for DONE strings :) */
468 if(strstr(tmp1,"%") == 0) {
469 if(strstr(tmp2,"%") == 0)
470 return 0; /* Both "DONE" */
471 else
472 return -1; /* A done, B not */
473 }
474 if(strstr(tmp2,"%")==0)
475 return 1; /* B done, A not */
476
477 /* Both have %, must remove */
478 tmp1 = STRDUP(GTK_CELL_TEXT(row1->cell[clist->sort_column])->text);
479 tmp2 = STRDUP(GTK_CELL_TEXT(row2->cell[clist->sort_column])->text);
480
481 tmp1[strlen(tmp1)-1]=0;
482 tmp2[strlen(tmp2)-1]=0;
483
484 value1 = atof(tmp1);
485 value2 = atof(tmp2);
486
487 FREE(tmp1);
488 FREE(tmp2);
489
490 if(value1>value2)
491 return(-1);
492 else if(value1==value2)
493 return(0);
494 else
495 return(1);
496}
497
498/* end of helper.c */
diff --git a/src/helper.h b/src/helper.h
new file mode 100644
index 00000000..3bf65f11
--- /dev/null
+++ b/src/helper.h
@@ -0,0 +1,139 @@
1/*
2 This file is part of GNUnet
3
4 GNUnet is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published
6 by the Free Software Foundation; either version 2, or (at your
7 option) any later version.
8
9 GNUnet is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNUnet; see the file COPYING. If not, write to the
16 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20/**
21 * @file src/helper.h
22 * @author Igor Wronsky
23 */
24
25#ifndef GTKUI_HELPER_H
26#define GTKUI_HELPER_H
27
28#include "platform.h"
29#include <GNUnet/gnunet_util.h>
30
31/* for GTK 2 */
32#define GTK_ENABLE_BROKEN
33
34#include <gtk/gtk.h>
35#include <gtk/gtktext.h>
36
37typedef struct {
38 Semaphore *sem;
39 void *args;
40 GtkFunction func;
41} SaveCall;
42
43typedef struct {
44 int doPopup;
45 gchar *note;
46} InfoMessage;
47
48typedef struct {
49 const char *labelName;
50 GtkWidget *frame;
51} AddNotebook;
52
53
54/* callback: window close: close the window */
55gint deleteEvent(GtkWidget * widget,
56 GdkEvent * event,
57 gpointer data);
58
59/**
60 * A callback to destroy any widget given as second argument
61 *
62 */
63void destroyWidget(GtkWidget * dummy, GtkWidget * widget);
64
65/**
66 * Displays an informative message to the user
67 */
68void guiMessage(const char * format, ...);
69
70/**
71 * Appends a message to the info window
72 */
73void infoMessage(int doPopup, const char * format, ...);
74
75/**
76 * Appends a log entry to the info window
77 *
78 * @param txt the log entry
79 *
80 */
81void addLogEntry(const char *txt);
82
83/**
84 * A function for numeric comparisons of strings
85 */
86gint numericComp(GtkCList *clist,
87 gconstpointer ptr1,
88 gconstpointer ptr2);
89
90/**
91 * A function for case-insensitive text comparisons
92 */
93gint alphaComp(GtkCList *clist,
94 gconstpointer ptr1,
95 gconstpointer ptr2);
96
97/**
98 * A function for comparisons of percentages
99 */
100gint percentComp(GtkCList *clist,
101 gconstpointer ptr1,
102 gconstpointer ptr2);
103
104/**
105 * A general right-button popup menu callback
106 */
107gboolean popupCallback(GtkWidget *widget,
108 GdkEvent *event,
109 GtkWidget *menu );
110
111/**
112 * Call a callback function from the mainloop/main thread ("SaveCall").
113 * Since GTK doesn't work with multi-threaded applications under Windows,
114 * all GTK operations have to be done in the main thread
115 */
116void gtkSaveCall(GtkFunction func, void *args);
117
118/**
119 * Initialize "SaveCalls"
120 */
121void gtkInitSaveCalls();
122
123void gtkDoneSaveCalls();
124
125int gtkRunSomeSaveCalls();
126
127/**
128 * Called from a "SaveCall"-function to indicate that it is done
129 */
130void gtkSaveCallDone(Semaphore *sem);
131
132/**
133 * Destroy a widget. Called from threads other than the main thread
134 */
135gint doDestroyWidget(SaveCall *call);
136
137extern GtkWidget * infoWindow;
138
139#endif
diff --git a/src/main.c b/src/main.c
index b4325e81..14525733 100644
--- a/src/main.c
+++ b/src/main.c
@@ -27,30 +27,18 @@
27#include "config.h" 27#include "config.h"
28#include "gettext.h" 28#include "gettext.h"
29 29
30#include <gtk/gtk.h>
31#include <glade/glade.h>
32
33#include <GNUnet/gnunet_util.h> 30#include <GNUnet/gnunet_util.h>
34#include <GNUnet/gnunet_ecrs_lib.h>
35#include <GNUnet/gnunet_fsui_lib.h>
36 31
37#include "main.h" 32#include "main.h"
38 33#include "fs.h"
39/** 34#include "daemon.h"
40 * FSUI event handler. 35#include "helper.h"
41 */
42static void eventProcessor(void * cls,
43 const FSUI_Event * event) {
44 printf("FSUI event received!\n");
45}
46 36
47/** 37/**
48 * Prints the usage information for this command if the user errs. 38 * Prints the usage information for this command if the user errs.
49 */ 39 */
50static void printhelp() { 40static void printhelp() {
51 static Help help[] = { 41 static Help help[] = {
52 { 'a', "anonymity", "LEVEL",
53 gettext_noop("set the desired LEVEL of receiver-anonymity") },
54 HELP_CONFIG, 42 HELP_CONFIG,
55 HELP_HELP, 43 HELP_HELP,
56 HELP_HOSTNAME, 44 HELP_HOSTNAME,
@@ -109,33 +97,42 @@ static int parseOptions(int argc,
109} 97}
110 98
111GladeXML * mainXML; 99GladeXML * mainXML;
112struct FSUI_Context * ctx;
113 100
114int main(int argc, 101int main(int argc,
115 char *argv[]) { 102 char *argv[]) {
116 103
104 g_thread_init(NULL);
117 gtk_init(&argc, &argv); 105 gtk_init(&argc, &argv);
118 if (SYSERR == initUtil(argc, 106 if (SYSERR == initUtil(argc,
119 argv, 107 argv,
120 &parseOptions)) 108 &parseOptions))
121 return 0; 109 return 0;
122 110 startCron();
111 gtkInitSaveCalls();
123 /* load the interface */ 112 /* load the interface */
124 mainXML = glade_xml_new(GLADE_FILE, 113 mainXML = glade_xml_new(GLADE_FILE,
125 "mainWindow", 114 "mainWindow",
126 NULL); 115 NULL);
127 /* connect the signals in the interface */ 116 /* connect the signals in the interface */
117 setCustomLogProc(&addLogEntry);
128 glade_xml_signal_autoconnect(mainXML); 118 glade_xml_signal_autoconnect(mainXML);
129 119 gtk_fs_init();
130 /* FSUI initialization here! */ 120 addCronJob(&cronCheckDaemon,
131 ctx = FSUI_start("gnunet-gtk", 121 0,
132 YES, 122 15 * cronSECONDS,
133 &eventProcessor, 123 NULL);
134 NULL);
135
136 /* start the event loop */ 124 /* start the event loop */
125 gdk_threads_enter();
137 gtk_main(); 126 gtk_main();
138 FSUI_stop(ctx); 127 gdk_threads_leave();
128 setCustomLogProc(NULL);
129 gtkDoneSaveCalls();
130 stopCron();
131 delCronJob(&cronCheckDaemon,
132 15 * cronSECONDS,
133 NULL);
134 gtk_fs_done();
135 g_object_unref(mainXML);
139 doneUtil(); 136 doneUtil();
140 137
141 return 0; 138 return 0;
diff --git a/src/main.h b/src/main.h
new file mode 100644
index 00000000..dfd1763e
--- /dev/null
+++ b/src/main.h
@@ -0,0 +1,35 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/main.h
23 * @brief globals of gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#ifndef MAIN_H
28#define MAIN_H
29
30#include <gtk/gtk.h>
31#include <glade/glade.h>
32
33extern GladeXML * mainXML;
34
35#endif
diff --git a/src/platform.h b/src/platform.h
new file mode 100644
index 00000000..2414e123
--- /dev/null
+++ b/src/platform.h
@@ -0,0 +1,175 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file include/platform.h
23 * @brief plaform specifics
24 *
25 * @author Nils Durner
26 */
27
28#ifndef PLATFORM_H
29#define PLATFORM_H
30
31#ifndef HAVE_USED_CONFIG_H
32#define HAVE_USED_CONFIG_H
33#include "config.h"
34#endif
35
36#include "gettext.h"
37
38#include "plibc.h"
39
40/**
41 * For strptime (glibc2 needs this).
42 */
43#ifndef _XOPEN_SOURCE
44#define _XOPEN_SOURCE
45#endif
46
47
48/* configuration options */
49
50#define VERBOSE_STATS 0
51
52#ifdef CYGWIN
53 #include <sys/reent.h>
54 #define _REENT_ONLY
55#endif
56
57#include <pthread.h>
58#ifdef CYGWIN
59 #undef _REENT_ONLY
60#endif
61
62#ifdef _MSC_VER
63 #include <Winsock2.h>
64#else
65#ifndef MINGW
66 #include <netdb.h>
67 #include <sys/socket.h>
68 #include <netinet/in.h>
69 #include <arpa/inet.h>
70 #include <netinet/tcp.h>
71 #include <netinet/in.h>
72 #include <pwd.h>
73 #include <sys/ioctl.h>
74#else
75 #include "winproc.h"
76#endif
77#endif
78
79#include <string.h>
80#include <stdio.h>
81#include <stdlib.h>
82#include <stdarg.h>
83#ifndef _MSC_VER
84#include <ltdl.h> /* KLB_FIX */
85#endif
86#include <errno.h>
87#include <signal.h>
88#ifndef _MSC_VER
89#include <unistd.h> /* KLB_FIX */
90#endif
91#include <sys/stat.h>
92#include <sys/types.h>
93#ifndef _MSC_VER
94#include <dirent.h> /* KLB_FIX */
95#endif
96#include <fcntl.h>
97#include <math.h>
98
99#if TIME_WITH_SYS_TIME
100 #include <sys/time.h>
101 #include <time.h>
102#else
103 #if HAVE_SYS_TIME_H
104 #include <sys/time.h>
105 #else
106 #include <time.h>
107 #endif
108#endif
109
110/* if we have both openssl & libgcrypt, stick
111 to openssl for now (who has the obscure
112 libgcrypt CVS version that works for us!?...) */
113#if USE_OPENSSL
114 #if USE_GCRYPT
115 #undef USE_GCRYPT
116 #define USE_GCRYPT 0
117 #endif
118#endif
119
120#ifdef SOMEBSD
121 #include <net/if.h>
122#endif
123#ifdef FREEBSD
124 #include <semaphore.h>
125#endif
126#ifdef OSX
127#include <semaphore.h>
128#endif
129#ifdef LINUX
130#include <net/if.h>
131#endif
132#ifdef SOLARIS
133#include <sys/sockio.h>
134#include <sys/loadavg.h>
135#include <semaphore.h>
136#endif
137#ifdef CYGWIN
138#include <windows.h>
139#include <cygwin/if.h>
140#endif
141#include <errno.h>
142
143#include <limits.h>
144
145#if HAVE_CTYPE_H
146#include <ctype.h>
147#endif
148
149#include <locale.h>
150#include "gettext.h"
151
152
153#ifdef CYGWIN
154 #define SIOCGIFCONF _IOW('s', 100, struct ifconf) /* get if list */
155 #define SIOCGIFFLAGS _IOW('s', 101, struct ifreq) /* Get if flags */
156 #define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
157#endif
158
159#ifndef MINGW
160#include <sys/mman.h>
161#endif
162
163#ifdef OSX
164 #define socklen_t unsigned int
165#endif
166
167#if !HAVE_ATOLL
168long long atoll(const char *nptr);
169#endif
170
171#if ENABLE_NLS
172 #include "langinfo.h"
173#endif
174
175#endif
diff --git a/src/plibc.h b/src/plibc.h
new file mode 100644
index 00000000..ab630526
--- /dev/null
+++ b/src/plibc.h
@@ -0,0 +1,565 @@
1/*
2 This file is part of PlibC.
3 (C) 2005 Nils Durner (and other contributing authors)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/
19
20/**
21 * @file include/plibc.h
22 * @brief PlibC header
23 * @attention This file is usually not installed under Unix,
24 * so ship it with your application
25 * @version $Revision: 1.16 $
26 */
27
28#ifndef _PLIBC_H_
29#define _PLIBC_H_
30
31#ifndef SIGALRM
32 #define SIGALRM 14
33#endif
34
35#if ENABLE_NLS
36 #include "langinfo.h"
37#endif
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43#ifdef WINDOWS
44
45#include <windows.h>
46#include <time.h>
47#include <stdio.h>
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <dirent.h>
51
52#define __BYTE_ORDER BYTE_ORDER
53#define __BIG_ENDIAN BIG_ENDIAN
54
55/* Conflicts with our definitions */
56#define __G_WIN32_H__
57
58/* Convert LARGE_INTEGER to double */
59#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + \
60 (double)((x).LowPart))
61
62#define socklen_t int
63#define ssize_t int
64#define ftruncate chsize
65#define off_t int
66#define int64_t long long
67#define int32_t long
68
69/* Thanks to the Cygwin project */
70#define EPERM 1 /* Not super-user */
71#define ENOENT 2 /* No such file or directory */
72#define ESRCH 3 /* No such process */
73#define EINTR 4 /* Interrupted system call */
74#define EIO 5 /* I/O error */
75#define ENXIO 6 /* No such device or address */
76#define E2BIG 7 /* Arg list too long */
77#define ENOEXEC 8 /* Exec format error */
78#define EBADF 9 /* Bad file number */
79#define ECHILD 10 /* No children */
80#define EAGAIN 11 /* Resource unavailable or operation would block, try again */
81#define ENOMEM 12 /* Not enough memory */
82#define EACCES 13 /* Permission denied */
83#define EFAULT 14 /* Bad address */
84#define ENOTBLK 15 /* Block device required */
85#define EBUSY 16 /* Mount device busy */
86#define EEXIST 17 /* File exists */
87#define EXDEV 18 /* Cross-device link */
88#define ENODEV 19 /* No such device */
89#define ENOTDIR 20 /* Not a directory */
90#define EISDIR 21 /* Is a directory */
91#define EINVAL 22 /* Invalid argument */
92#define ENFILE 23 /* Too many open files in system */
93#define EMFILE 24 /* Too many open files */
94#define ENOTTY 25 /* Not a typewriter */
95#define ETXTBSY 26 /* Text file busy */
96#define EFBIG 27 /* File too large */
97#define ENOSPC 28 /* No space left on device */
98#define ESPIPE 29 /* Illegal seek */
99#define EROFS 30 /* Read only file system */
100#define EMLINK 31 /* Too many links */
101#define EPIPE 32 /* Broken pipe */
102#define EDOM 33 /* Math arg out of domain of func */
103#define ERANGE 34 /* Math result not representable */
104#define ENOMSG 35 /* No message of desired type */
105#define EIDRM 36 /* Identifier removed */
106#define ECHRNG 37 /* Channel number out of range */
107#define EL2NSYNC 38 /* Level 2 not synchronized */
108#define L3HLT 39 /* Level 3 halted */
109#define EL3RST 40 /* Level 3 reset */
110#define ELNRNG 41 /* Link number out of range */
111#define EUNATCH 42 /* Protocol driver not attached */
112#define ENOCSI 43 /* No CSI structure available */
113#define EL2HLT 44 /* Level 2 halted */
114#undef EDEADLK
115#define EDEADLK 45 /* Deadlock condition */
116#undef ENOLCK
117#define ENOLCK 46 /* No record locks available */
118#define EBADE 50 /* Invalid exchange */
119#define EBADR 51 /* Invalid request descriptor */
120#define EXFULL 52 /* Exchange full */
121#define ENOANO 53 /* No anode */
122#define EBADRQC 54 /* Invalid request code */
123#define EBADSLT 55 /* Invalid slot */
124#undef EDEADLOCK
125#define EDEADLOCK 56 /* File locking deadlock error */
126#define EBFONT 57 /* Bad font file fmt */
127#define ENOSTR 60 /* Device not a stream */
128#define ENODATA 61 /* No data (for no delay io) */
129#define ETIME 62 /* Timer expired */
130#define ENOSR 63 /* Out of streams resources */
131#define ENONET 64 /* Machine is not on the network */
132#define ENOPKG 65 /* Package not installed */
133#define EREMOTE 66 /* The object is remote */
134#define ENOLINK 67 /* The link has been severed */
135#define EADV 68 /* Advertise error */
136#define ESRMNT 69 /* Srmount error */
137#define ECOMM 70 /* Communication error on send */
138#define EPROTO 71 /* Protocol error */
139#define EMULTIHOP 74 /* Multihop attempted */
140#define ELBIN 75 /* Inode is remote (not really error) */
141#define EDOTDOT 76 /* Cross mount point (not really error) */
142#define EBADMSG 77 /* Trying to read unreadable message */
143#define ENOTUNIQ 80 /* Given log. name not unique */
144#define EBADFD 81 /* f.d. invalid for this operation */
145#define EREMCHG 82 /* Remote address changed */
146#define ELIBACC 83 /* Can't access a needed shared lib */
147#define ELIBBAD 84 /* Accessing a corrupted shared lib */
148#define ELIBSCN 85 /* .lib section in a.out corrupted */
149#define ELIBMAX 86 /* Attempting to link in too many libs */
150#define ELIBEXEC 87 /* Attempting to exec a shared library */
151#undef ENOSYS
152#define ENOSYS 88 /* Function not implemented */
153#define ENMFILE 89 /* No more files */
154#undef ENOTEMPTY
155#define ENOTEMPTY 90 /* Directory not empty */
156#undef ENAMETOOLONG
157#define ENAMETOOLONG 91 /* File or path name too long */
158#define ELOOP 92 /* Too many symbolic links */
159#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
160#define EPFNOSUPPORT 96 /* Protocol family not supported */
161#define ECONNRESET 104 /* Connection reset by peer */
162#define ENOBUFS 105 /* No buffer space available */
163#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
164#define EPROTOTYPE 107 /* Protocol wrong type for socket */
165#define ENOTSOCK 108 /* Socket operation on non-socket */
166#define ENOPROTOOPT 109 /* Protocol not available */
167#define ESHUTDOWN 110 /* Can't send after socket shutdown */
168#define ECONNREFUSED 111 /* Connection refused */
169#define EADDRINUSE 112 /* Address already in use */
170#define ECONNABORTED 113 /* Connection aborted */
171#define ENETUNREACH 114 /* Network is unreachable */
172#define ENETDOWN 115 /* Network interface is not configured */
173#undef ETIMEDOUT
174#define ETIMEDOUT 116 /* Connection timed out */
175#define EHOSTDOWN 117 /* Host is down */
176#define EHOSTUNREACH 118 /* Host is unreachable */
177#define EINPROGRESS 119 /* Connection already in progress */
178#define EALREADY 120 /* Socket already connected */
179#define EDESTADDRREQ 121 /* Destination address required */
180#define EMSGSIZE 122 /* Message too long */
181#define EPROTONOSUPPORT 123 /* Unknown protocol */
182#define ESOCKTNOSUPPORT 124 /* Socket type not supported */
183#define EADDRNOTAVAIL 125 /* Address not available */
184#define ENETRESET 126 /* Connection aborted by network */
185#define EISCONN 127 /* Socket is already connected */
186#define ENOTCONN 128 /* Socket is not connected */
187#define ETOOMANYREFS 129 /* Too many references: cannot splice */
188#define EPROCLIM 130 /* Too many processes */
189#define EUSERS 131 /* Too many users */
190#define EDQUOT 132 /* Disk quota exceeded */
191#define ESTALE 133 /* Unknown error */
192#undef ENOTSUP
193#define ENOTSUP 134 /* Not supported */
194#define ENOMEDIUM 135 /* No medium (in tape drive) */
195#define ENOSHARE 136 /* No such host or network path */
196#define ECASECLASH 137 /* Filename exists with different case */
197#define EWOULDBLOCK EAGAIN /* Operation would block */
198
199#undef HOST_NOT_FOUND
200#define HOST_NOT_FOUND 1
201#undef TRY_AGAIN
202#define TRY_AGAIN 2
203#undef NO_RECOVERY
204#define NO_RECOVERY 3
205#undef NO_ADDRESS
206#define NO_ADDRESS 4
207
208#define PROT_READ 0x1
209#define PROT_WRITE 0x2
210#define MAP_SHARED 0x1
211#define MAP_PRIVATE 0x2 /* unsupported */
212#define MAP_FIXED 0x10
213
214struct statfs
215{
216 long f_type; /* type of filesystem (see below) */
217 long f_bsize; /* optimal transfer block size */
218 long f_blocks; /* total data blocks in file system */
219 long f_bfree; /* free blocks in fs */
220 long f_bavail; /* free blocks avail to non-superuser */
221 long f_files; /* total file nodes in file system */
222 long f_ffree; /* free file nodes in fs */
223 long f_fsid; /* file system id */
224 long f_namelen; /* maximum length of filenames */
225 long f_spare[6]; /* spare for later */
226};
227
228/* Taken from the Wine project <http://www.winehq.org>
229 /wine/include/winternl.h */
230enum SYSTEM_INFORMATION_CLASS
231{
232 SystemBasicInformation = 0,
233 Unknown1,
234 SystemPerformanceInformation = 2,
235 SystemTimeOfDayInformation = 3, /* was SystemTimeInformation */
236 Unknown4,
237 SystemProcessInformation = 5,
238 Unknown6,
239 Unknown7,
240 SystemProcessorPerformanceInformation = 8,
241 Unknown9,
242 Unknown10,
243 SystemDriverInformation,
244 Unknown12,
245 Unknown13,
246 Unknown14,
247 Unknown15,
248 SystemHandleList,
249 Unknown17,
250 Unknown18,
251 Unknown19,
252 Unknown20,
253 SystemCacheInformation,
254 Unknown22,
255 SystemInterruptInformation = 23,
256 SystemExceptionInformation = 33,
257 SystemRegistryQuotaInformation = 37,
258 SystemLookasideInformation = 45
259};
260
261typedef struct
262{
263 LARGE_INTEGER IdleTime;
264 LARGE_INTEGER KernelTime;
265 LARGE_INTEGER UserTime;
266 LARGE_INTEGER Reserved1[2];
267 ULONG Reserved2;
268} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
269
270#define sleep(secs) (Sleep(secs * 1000))
271
272/*********************** statfs *****************************/
273/* fake block size */
274#define FAKED_BLOCK_SIZE 512
275
276/* linux-compatible values for fs type */
277#define MSDOS_SUPER_MAGIC 0x4d44
278#define NTFS_SUPER_MAGIC 0x5346544E
279
280/*********************** End of statfs ***********************/
281
282#define SHUT_RDWR SD_BOTH
283
284/* Operations for flock() */
285#define LOCK_SH 1 /* shared lock */
286#define LOCK_EX 2 /* exclusive lock */
287#define LOCK_NB 4 /* or'd with one of the above to prevent
288 blocking */
289#define LOCK_UN 8 /* remove lock */
290
291/* Not supported under MinGW */
292#define S_IRGRP 0
293#define S_IWGRP 0
294#define S_IROTH 0
295#define S_IXGRP 0
296#define S_IWOTH 0
297#define S_IXOTH 0
298#define S_ISUID 0
299#define S_ISGID 0
300#define S_ISVTX 0
301#define S_IRWXG 0
302#define S_IRWXO 0
303
304#define SetErrnoFromWinError(e) _SetErrnoFromWinError(e, __FILE__, __LINE__)
305
306/**
307 * @brief index() - same as strchr()
308 */
309#define index(s, c) strchr(s, c)
310
311BOOL _plibc_CreateShortcut(const char *pszSrc, const char *pszDest);
312BOOL _plibc_DereferenceShortcut(char *pszShortcut);
313long QueryRegistry(HKEY hMainKey, char *pszKey, char *pszSubKey,
314 char *pszBuffer, long *pdLength);
315
316BOOL __win_IsHandleMarkedAsBlocking(SOCKET hHandle);
317void __win_SetHandleBlockingMode(SOCKET s, BOOL bBlocking);
318void __win_DiscardHandleBlockingMode(SOCKET s);
319int _win_isSocketValid(int s);
320int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows);
321
322typedef void (*TPanicProc) (int, char *);
323void plibc_set_panic_proc(TPanicProc proc);
324
325int flock(int fd, int operation);
326int fsync(int fildes);
327int inet_pton(int af, const char *src, void *dst);
328int inet_pton4(const char *src, u_char *dst, int pton);
329#if USE_IPV6
330int inet_pton6(const char *src, u_char *dst);
331#endif
332int truncate(const char *fname, int distance);
333int statfs(const char *path, struct statfs *buf);
334const char *hstrerror(int err);
335void gettimeofday(struct timeval *tp, void *tzp);
336int mkstemp(char *tmplate);
337char *strptime (const char *buf, const char *format, struct tm *tm);
338char *ctime(const time_t *clock);
339char *ctime_r(const time_t *clock, char *buf);
340int plibc_init(char *pszOrg, char *pszApp);
341void plibc_shutdown(void);
342int plibc_conv_to_win_path_ex(const char *pszUnix, char *pszWindows, int derefLinks);
343void _SetErrnoFromWinError(long lWinError, char *pszCaller, int iLine);
344void SetErrnoFromWinsockError(long lWinError);
345void SetHErrnoFromWinError(long lWinError);
346void SetErrnoFromHRESULT(HRESULT hRes);
347FILE *_win_fopen(const char *filename, const char *mode);
348DIR *_win_opendir(const char *dirname);
349int _win_open(const char *filename, int oflag, ...);
350#ifdef ENABLE_NLS
351char *_win_bindtextdomain(const char *domainname, const char *dirname);
352#endif
353int _win_chdir(const char *path);
354int _win_close(int fd);
355int _win_creat(const char *path, mode_t mode);
356int _win_fstat(int handle, struct stat *buffer);
357int _win_pipe(int *phandles);
358int _win_rmdir(const char *path);
359int _win_access( const char *path, int mode );
360int _win_chmod(const char *filename, int pmode);
361char *realpath(const char *file_name, char *resolved_name);
362int _win_remove(const char *path);
363int _win_rename(const char *oldname, const char *newname);
364int _win_stat(const char *path, struct stat *buffer);
365int _win_unlink(const char *filename);
366int _win_write(int fildes, const void *buf, size_t nbyte);
367int _win_read(int fildes, void *buf, size_t nbyte);
368size_t _win_fwrite(const void *buffer, size_t size, size_t count, FILE *stream);
369size_t _win_fread( void *buffer, size_t size, size_t count, FILE *stream );
370int _win_symlink(const char *path1, const char *path2);
371void *_win_mmap(void *start, size_t len, int access, int flags, int fd,
372 unsigned long long offset);
373int _win_munmap(void *start, size_t length);
374int _win_lstat(const char *path, struct stat *buf);
375int _win_readlink(const char *path, char *buf, size_t bufsize);
376int _win_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
377int _win_printf(const char *format,...);
378int _win_fprintf(FILE *f,const char *format,...);
379int _win_vprintf(const char *format, va_list ap);
380int _win_vfprintf(FILE *stream, const char *format, va_list arg_ptr);
381int _win_vsprintf(char *dest,const char *format, va_list arg_ptr);
382int _win_vsnprintf(char* str, size_t size, const char *format, va_list arg_ptr);
383int _win_snprintf(char *str,size_t size,const char *format,...);
384int _win_sprintf(char *dest,const char *format,...);
385int _win_vsscanf(const char* str, const char* format, va_list arg_ptr);
386int _win_sscanf(const char *str, const char *format, ...);
387int _win_vfscanf(FILE *stream, const char *format, va_list arg_ptr);
388int _win_vscanf(const char *format, va_list arg_ptr);
389int _win_scanf(const char *format, ...);
390int _win_fscanf(FILE *stream, const char *format, ...);
391int _win_bind(SOCKET s, const struct sockaddr *name, int namelen);
392int _win_connect(SOCKET s,const struct sockaddr *name, int namelen);
393int _win_getpeername(SOCKET s, struct sockaddr *name,
394 int *namelen);
395int _win_getsockname(SOCKET s, struct sockaddr *name,
396 int *namelen);
397int _win_getsockopt(SOCKET s, int level, int optname, char *optval,
398 int *optlen);
399int _win_listen(SOCKET s, int backlog);
400int _win_recv(SOCKET s, char *buf, int len, int flags);
401int _win_recvfrom(SOCKET s, void *buf, int len, int flags,
402 struct sockaddr *from, int *fromlen);
403int _win_select(int max_fd, fd_set * rfds, fd_set * wfds, fd_set * efds,
404 const struct timeval *tv);
405int _win_send(SOCKET s, const char *buf, int len, int flags);
406int _win_sendto(SOCKET s, const char *buf, int len, int flags,
407 const struct sockaddr *to, int tolen);
408int _win_setsockopt(SOCKET s, int level, int optname, const void *optval,
409 int optlen);
410int _win_shutdown(SOCKET s, int how);
411SOCKET _win_socket(int af, int type, int protocol);
412struct hostent *_win_gethostbyaddr(const char *addr, int len, int type);
413struct hostent *_win_gethostbyname(const char *name);
414char *_win_strerror(int errnum);
415int IsWinNT(void);
416
417#if !HAVE_STRNDUP
418char *strndup (const char *s, size_t n);
419#endif
420#if !HAVE_STRNLEN
421size_t strnlen (const char *str, size_t maxlen);
422#endif
423
424#endif /* WINDOWS */
425
426#ifndef WINDOWS
427 #define DIR_SEPARATOR '/'
428 #define DIR_SEPARATOR_STR "/"
429 #define NEWLINE "\n"
430
431#ifdef ENABLE_NLS
432 #define BINDTEXTDOMAIN(d, n) bindtextdomain(d, n)
433#endif
434 #define CREAT(p, m) creat(p, m)
435 #undef FOPEN
436 #define FOPEN(f, m) fopen(f, m)
437 #define OPENDIR(d) opendir(d)
438 #define OPEN(f) open(f)
439 #define CHDIR(d) chdir(d)
440 #define CLOSE(f) close(f)
441 #define RMDIR(f) rmdir(f)
442 #define ACCESS(p, m) access(p, m)
443 #define CHMOD(f, p) chmod(f, p)
444 #define FSTAT(h, b) fstat(h, b)
445 #define PIPE(h) pipe(h)
446 #define REMOVE(p) remove(p)
447 #define RENAME(o, n) rename(o, n)
448 #define STAT(p, b) stat(p, b)
449 #define UNLINK(f) unlink(f)
450 #define WRITE(f, b, n) write(f, b, n)
451 #define READ(f, b, n) read(f, b, n)
452 #define GN_FREAD(b, s, c, f) fread(b, s, c, f)
453 #define GN_FWRITE(b, s, c, f) fwrite(b, s, c, f)
454 #define SYMLINK(a, b) symlink(a, b)
455 #define MMAP(s, l, p, f, d, o) mmap(s, l, p, f, d, o)
456 #define MUNMAP(s, l) munmap(s, l)
457 #define STRERROR(i) strerror(i)
458 #define READLINK(p, b, s) readlink(p, b, s)
459 #define LSTAT(p, b) lstat(p, b)
460 #define PRINTF(f, ...) printf(f , __VA_ARGS__)
461 #define FPRINTF(fil, fmt, ...) fprintf(fil, fmt, __VA_ARGS__)
462 #define VPRINTF(f, a) vprintf(f, a)
463 #define VFPRINTF(s, f, a) vfprintf(s, f, a)
464 #define VSPRINTF(d, f, a) vsprintf(d, f, a)
465 #define VSNPRINTF(str, size, fmt, a) vsnprintf(str, size, fmt, a)
466 #define _REAL_SNPRINTF(str, size, fmt, ...) snprintf(str, size, fmt, __VA_ARGS__)
467 #define SPRINTF(d, f, ...) sprintf(d, f, __VA_ARGS__)
468 #define VSSCANF(s, f, a) vsscanf(s, f, a)
469 #define SSCANF(s, f, ...) sscanf(s, f, __VA_ARGS__)
470 #define VFSCANF(s, f, a) vfscanf(s, f, a)
471 #define VSCANF(f, a) vscanf(f, a)
472 #define SCANF(f, ...) scanf(f, __VA_ARGS__)
473 #define FSCANF(s, f, ...) fscanf(s, f, __VA_ARGS__)
474 #define ACCEPT(s, a, l) accept(s, a, l)
475 #define BIND(s, n, l) bind(s, n, l)
476 #define CONNECT(s, n, l) connect(s, n, l)
477 #define GETPEERNAME(s, n, l) getpeername(s, n, l)
478 #define GETSOCKNAME(s, n, l) getsockname(s, n, l)
479 #define GETSOCKOPT(s, l, o, v, p) getsockopt(s, l, o, v, p)
480 #define LISTEN(s, b) listen(s, b)
481 #define RECV(s, b, l, f) recv(s, b, l, f)
482 #define RECVFROM(s, b, l, f, r, o) recvfrom(s, b, l, f, r, o)
483 #define SELECT(n, r, w, e, t) select(n, r, w, e, t)
484 #define SEND(s, b, l, f) send(s, b, l, f)
485 #define SENDTO(s, b, l, f, o, n) sendto(s, b, l, f, o, n)
486 #define SETSOCKOPT(s, l, o, v, n) setsockopt(s, l, o, v, n)
487 #define SHUTDOWN(s, h) shutdown(s, h)
488 #define SOCKET(a, t, p) socket(a, t, p)
489 #define GETHOSTBYADDR(a, l, t) gethostbyname(a, l, t)
490 #define GETHOSTBYNAME(n) gethostbyname(n)
491#else
492 #define DIR_SEPARATOR '\\'
493 #define DIR_SEPARATOR_STR "\\"
494 #define NEWLINE "\r\n"
495
496#ifdef ENABLE_NLS
497 #define BINDTEXTDOMAIN(d, n) _win_bindtextdomain(d, n)
498#endif
499 #define CREAT(p, m) _win_creat(p, m)
500 #define FOPEN(f, m) _win_fopen(f, m)
501 #define OPENDIR(d) _win_opendir(d)
502 #define OPEN(f) _win_open(f)
503 #define CHDIR(d) _win_chdir(d)
504 #define CLOSE(f) _win_close(f)
505 #define FSTAT(h, b) _win_fstat(h, b)
506 #define RMDIR(f) _win_rmdir(f)
507 #define ACCESS(p, m) _win_access(p, m)
508 #define CHMOD(f, p) _win_chmod(f, p)
509 #define PIPE(h) _win_pipe(h)
510 #define REMOVE(p) _win_remove(p)
511 #define RENAME(o, n) _win_rename(o, n)
512 #define STAT(p, b) _win_stat(p, b)
513 #define UNLINK(f) _win_unlink(f)
514 #define WRITE(f, b, n) _win_write(f, b, n)
515 #define READ(f, b, n) _win_read(f, b, n)
516 #define GN_FREAD(b, s, c, f) _win_fread(b, s, c, f)
517 #define GN_FWRITE(b, s, c, f) _win_fwrite(b, s, c, f)
518 #define SYMLINK(a, b) _win_symlink(a, b)
519 #define MMAP(s, l, p, f, d, o) _win_mmap(s, l, p, f, d, o)
520 #define MUNMAP(s, l) _win_munmap(s, l)
521 #define STRERROR(i) _win_strerror(i)
522 #define READLINK(p, b, s) _win_readlink(p, b, s)
523 #define LSTAT(p, b) _win_lstat(p, b)
524 #define PRINTF(f, ...) _win_printf(f , __VA_ARGS__)
525 #define FPRINTF(fil, fmt, ...) _win_fprintf(fil, fmt, __VA_ARGS__)
526 #define VPRINTF(f, a) _win_vprintf(f, a)
527 #define VFPRINTF(s, f, a) _win_vfprintf(s, f, a)
528 #define VSPRINTF(d, f, a) _win_vsprintf(d, f, a)
529 #define VSNPRINTF(str, size, fmt, a) _win_vsnprintf(str, size, fmt, a)
530 #define _REAL_SNPRINTF(str, size, fmt, ...) _win_snprintf(str, size, fmt, __VA_ARGS__)
531 #define SPRINTF(d, f, ...) _win_sprintf(d, f, __VA_ARGS__)
532 #define VSSCANF(s, f, a) _win_vsscanf(s, f, a)
533 #define SSCANF(s, f, ...) _win_sscanf(s, f, __VA_ARGS__)
534 #define VFSCANF(s, f, a) _win_vfscanf(s, f, a)
535 #define VSCANF(f, a) _win_vscanf(f, a)
536 #define SCANF(f, ...) _win_scanf(f, __VA_ARGS__)
537 #define FSCANF(s, f, ...) _win_fscanf(s, f, __VA_ARGS__)
538 #define ACCEPT(s, a, l) _win_accept(s, a, l)
539 #define BIND(s, n, l) _win_bind(s, n, l)
540 #define CONNECT(s, n, l) _win_connect(s, n, l)
541 #define GETPEERNAME(s, n, l) _win_getpeername(s, n, l)
542 #define GETSOCKNAME(s, n, l) _win_getsockname(s, n, l)
543 #define GETSOCKOPT(s, l, o, v, p) _win_getsockopt(s, l, o, v, p)
544 #define LISTEN(s, b) _win_listen(s, b)
545 #define RECV(s, b, l, f) _win_recv(s, b, l, f)
546 #define RECVFROM(s, b, l, f, r, o) _win_recvfrom(s, b, l, f, r, o)
547 #define SELECT(n, r, w, e, t) _win_select(n, r, w, e, t)
548 #define SEND(s, b, l, f) _win_send(s, b, l, f)
549 #define SENDTO(s, b, l, f, o, n) _win_sendto(s, b, l, f, o, n)
550 #define SETSOCKOPT(s, l, o, v, n) _win_setsockopt(s, l, o, v, n)
551 #define SHUTDOWN(s, h) _win_shutdown(s, h)
552 #define SOCKET(a, t, p) _win_socket(a, t, p)
553 #define GETHOSTBYADDR(a, l, t) _win_gethostbyname(a, l, t)
554 #define GETHOSTBYNAME(n) _win_gethostbyname(n)
555#endif
556
557
558#ifdef __cplusplus
559}
560#endif
561
562
563#endif //_PLIBC_H_
564
565/* end of plibc.h */
diff --git a/todo b/todo
index b3998aa4..61826fe4 100644
--- a/todo
+++ b/todo
@@ -1,17 +1,20 @@
1High priority: 1High priority:
2* figure out how list views work 2* figure out how list views work
3* decide between C and C++ 3* basic FS integration:
4 (figure out how to inspect internals of 4 - search:
5 object tree in C / C++) 5 + properly get page from glade window
6* basic FS integration (insert, search, download) 6 + properly initialize tree view
7* better widget naming -- conventions? 7 + process search result events
8 + process search frame close event
9 + support namespace URIs
10 + update namespace list combo box
11 - insert
12 - download
8 13
9Important: 14Important:
10* look at pango for welcome/splash screen
11* advanced FS operations (namespace, collection) 15* advanced FS operations (namespace, collection)
12* stats integration 16* stats integration
13* available apps 17* available apps
14* about dialog
15 18
16Later: 19Later:
17* more help-texts 20* more help-texts