September 26, 2022, 06:24:38 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Glade Demo #1: Base64 Encode/Decode

Started by Armando Rivera, September 06, 2008, 12:04:16 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Armando Rivera

September 06, 2008, 12:04:16 AM Last Edit: September 06, 2008, 10:59:21 PM by Armando Rivera
Since I hadn't seen any examples using Glade, I decided to roll my own and share.

***UPDATE***
Removed the calls to the GLib-provided Base64 routines, and implemented
native routines, to avoid potential GLib version issues.


Screenshots:





Source:
'~ base64_demo
'~ copyright 2008, Armando I. Rivera / Recursive Media Group
'~ Demonstrates how to use libGlade with Emergence Basic

'~ ************************************************************************
'~ *  NOTE: ALL EVENT ROUTINE SUBS NEED TO BE DECLARED GLOBAL    *
'~ *  IN ORDER FOR GLADE TO FIND THEM                                               *
'~ ************************************************************************

'~ Compile with Target=GTK 2.0

'~ FORCE DECLARATION OF ALL VARIABLES
autodefine "off"

'~ PROGRAM ENTRY POINT
$main

'~ INCLUDE BASE64.INC FILE
$include "base64.inc"

'~ LINKER FLAGS
'~ -s STRIPS THE EXECUTABLE, REDUCING SIZE.  OPTIONAL. DISABLE IF DEBUGGING
'~ "-E", OR "--EXPORT DYNAMIC" IS REQUIRED FOR LIBGLADE'S SIGNAL AUTOCONNECT FEATURE
'~ "-lglade-2.0" LINKS THE LIBGLADE LIBRARY
$use "-s -E -lglade-2.0"

'~ API DECLARATIONS. SEE THE GTK DOCS FOR DETAILS
declare cdecl extern glade_xml_new (string XML_FILE,string ROOT_NODE),pointer
declare cdecl extern glade_xml_get_widget (pointer XML_INSTANCE, string XML_OBJECT),pointer
declare cdecl extern glade_xml_signal_autoconnect(pointer WIDGET)
declare cdecl extern g_object_get(pointer object,string propname,...)
declare cdecl extern g_object_set(pointer object,string propname,...)
declare cdecl extern g_base64_encode(string text_to_encode,uint text_len),string
declare cdecl extern g_base64_decode(string text_to_decode,pointer text_len),string
declare cdecl extern g_free(pointer gmem)
declare cdecl extern g_object_unref(pointer gobject)



'~ MAKE SURE THE GLADE FILE IS AVAILABLE, ELSE BAIL
bfile chkFile
int run
if openfile(chkFile,GETSTARTPATH+"B64.glade","R")=0
  closefile(chkFile)
  '~ VARIABLES THAT WILL POINT TO WINDOW OBJECT HANDLES
  pointer GladeFile,window1,txtEncode,txtEncodeOutput,txtDecode,txtDecodeOutput

'~ LOAD UP THE GLADE DEFINITION FILE
  GladeFile=glade_xml_new(GETSTARTPATH+"B64.glade","window1")

'~ Interesting bit:  You only need handles to objects you need to manipulate directly when using Glade and AutoConnect.
'~ All other objects, like the main Window, for example, don't need to have a handle created
'~ if we're not doing anything with it like changing the Title or setting it's destroy method in code.
  '~ window1=glade_xml_get_widget(GladeFile,"window1")
  txtEncode=glade_xml_get_widget(GladeFile,"txtEncode")
  txtEncodeOutput=glade_xml_get_widget(GladeFile,"textEncodeOutput")
  txtDecode=glade_xml_get_widget(GladeFile,"txtDecode")
  txtDecodeOutput=glade_xml_get_widget(GladeFile,"textDecodeOutput")

'~ AUTOCONNECT THE EVENT SIGNALS TO THE HANDLERS SPECIFIED IN THE GLADE FILE
  glade_xml_signal_autoconnect(GladeFile)

  '~ testing property set
  '~ g_object_set(window1,"title","Changing the FORM Title in Code",0)

  '~ START THE PROGRAM MAIN LOOP
  run=true
  waituntil run=false
else
'~ GLADE DEF FILE NOT FOUND
  print ("GLADE FILE \"B64.glade\" IS NOT IN PROGRAM DIRECTORY")
  closefile(chkFile)
end if
end

'~ ROUTINE CALLED WHEN FORM IS CLOSED TO EXIT APPLICATION
global sub on_window1_destroy()
  run=false
end sub

'~ ENCODE BUTTON CLICK EVENT HANDLER
global sub on_btnEncode_clicked
  start_process(txtEncode,txtEncodeOutput,"Encode")
end sub

'~ ENCODE CLEAR BUTTON CLICK EVENT HANDLER
global sub on_btnEncodeClear_clicked
  clear_views(txtEncode,txtEncodeOutput)
end sub

'~ DECODE BUTTON CLICK EVENT HANDLER
global sub on_btnDecode_clicked
  start_process(txtDecode,txtDecodeOutput,"Decode")
end sub

'~ DECODE CLEAR BUTTON CLICK EVENT HANDLER
global sub on_btnDecodeClear_clicked
  clear_views(txtDecode,txtDecodeOutput)
end sub

'~ ROUTINE TO CLEAR CONTENTS OF GTKENTRY/GTKTEXTVIEW
'~ POINTERS TO GTKENTRY AND GTKTEXTVIEW ARE PASSED
'~ IN ORDER TO SERVICE OBJECTS ON MULTIPLE TABS
sub clear_views(entryHnd as pointer, textviewHnd as pointer)
    pointer textbuffer
    '~ GET THE HANDLE TO THE GTKTEXVIEW'S GTKTEXTBUFFER
    '~ HANDLE IS PASSED TO textbuffer POINTER VARIABLE
    g_object_get(textviewHnd,"buffer",&textbuffer,0)

    '~ CLEAR THE GTKTEXTBUFFER
    g_object_set(textbuffer,"text","",0)

    '~ CLEAR THE GTKENTRY
    g_object_set(entryHnd,"text","",0)

    '~ FREE UP MEMORY ALLOCATED TO THE textbuffer OBJECT
    g_object_unref(textbuffer)
end sub

'~ ROUTINE TO BEGIN THE ACTUAL ENCODING/DECODING
'~ POINTERS TO GTKENTRY/GTKTEXTVIEW ARE PASSED
'~ ALONG WITH THE TYPE OF OPERATION DESIRED (ENCODE OR DECODE)
sub start_process(entryHnd as pointer, textviewHnd as pointer, operation as string)
  pointer textbuffer,p1,source_string_len

  string source_string,encoded_string,lc_string
  lc_string=lcase$(operation)

'~ GET THE TEXT CONTENTS OF GTKENTRY AND ASSIGN TO STRING VAR
  g_object_get(entryHnd,"text",&p1,0)
  source_string=*<string>p1

  '~ FREE THE MEMORY USED BY POINTER p1
  '~ g_object_get MAKES A COPY OF THE DATA RETRIEVED,
  '~ LEAVING IT TO THE CALLER TO FREE THE MEMORY ALLOCATED
  '~ ONCE THE DATA HAS BEEN RETRIEVED/USED
  '~ g_object_unref would be used for objects
  g_free(p1)

'~ CHECK IF THERE'S ANY ACTUAL TEXT
  if len(source_string) then

'~ ENCODE, OR DECODE, OR ABORT
    select lc_string '(lcase$(operation))
      case "encode"
      '~ ENCODE IT USING GLIB FUNCTION
        encoded_string=ENCODE64(source_string)
      case "decode"
      '~ DECODE IT USING GLIB FUNCTION
        encoded_string=DECODE64(source_string)
    end select

    '~ GET THE HANDLE TO THE GTKTEXVIEW'S GTKTEXTBUFFER
    g_object_get(textviewHnd,"buffer",&textbuffer,0)

    '~ GET THE ASC VALUE OF THE FIRST CHARACTER IN THE
    '~ RETURNED STRING
    int first_char:first_char= asc(encoded_string)

    '~ FILTER TO CHECK IF WITHIN SAFE ASCII RANGE
    if ((first_char > 31) and (first_char<128)) then
    '~SET THE GTKTEXTBUFFER'S CONTENTS TO THE ENCODED STRING
        g_object_set(textbuffer,"text",encoded_string,0)
    else
    '~ NOT IN SAFE RANGE. NOTIFY USER
        g_object_set(textbuffer,"text","** Invalid Entry **",0)
    end if
    '~ FREE UP MEMORY ALLOCATED TO THE textbuffer OBJECT
    g_object_unref(textbuffer)

  end if
end sub



base64.inc:
'base64.inc Copyright 2007-2008 Armando I. Rivera, Recursive Media Group
'Updated: Sept 7, 2008

'Usage:
' ENCODE64(<string>) returns encoded string
' DECODE64(<string>) returns decoded string


sub ENCODE64(szUnEncoded AS STRING),string

  ' Create variables
  int icLowFill,iChar,iLowMask,iPtr,iCounter,icBitShift,icChopMask,iHighMask,iShift,iRollOver
  string szTemp

  '~ ' Initialize lookup dictionary and constants
   string szAlphabet:szAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

    icBitShift = 4
    icChopMask = 255
    icLowFill = 3


  ' Initialize Masks
    szTemp = ""

    iHighMask = 252
    iLowMask = 3
    iShift = 16
    iRollOver = 0


  ' Begin Encoding process
    FOR iCounter = 1 TO LEN(szUnEncoded)

  ' Fetch ascii character in passed string
        iChar = ASC(MID$(szUnEncoded, iCounter, 1))

  ' Calculate Alphabet lookup pointer
        iPtr = ((iChar & iHighMask) / (iLowMask + 1)) | iRollOver

  ' Roll bit patterns
        iRollOver = (iChar & iLowMask) * iShift

  ' Concatenate encoded character to working encoded string
        szTemp += MID$(szAlphabet, iPtr + 1, 1)

  ' Adjust masks
        iHighMask = (iHighMask * icBitShift) & icChopMask
        iLowMask = iLowMask * icBitShift + icLowFill
        iShift = iShift / icBitShift

  ' If last character in block, concat last RollOver and
  '   reset masks
        IF iHighMask = 0 THEN
            szTemp += MID$(szAlphabet, iRollOver + 1, 1)
            iRollOver = 0
            iHighMask = 252
            iLowMask = 3
            iShift = 16
        END IF

    NEXT iCounter

  ' If RollOver remains, concat it to the working string
    IF iShift < 16 THEN
        szTemp += MID$(szAlphabet, iRollOver + 1, 1)
    END IF

  ' Pad encoded string with required '=' pad characters
    iPtr = (LEN(szTemp) % 4)
    IF iPtr THEN szTemp += STRING$(4 - iPtr, "=")

  ' Return encoded string
    return szTemp
END sub

sub DECODE64 (string szEncoded),string

  ' Create variables
  int icLowFill,iChar,iLowMask,iPtr,iCounter,icBitShift,icChopMask,iHighMask,iShift,iRollOver,iLowShift,icStartMask
  string szTemp,szAlphabet

' Initialize lookup dictionary
    szAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

' Initialize Constants
    icChopMask = 255
    icBitShift = 4
    icStartMask = 16

' Initialize Masks
    iShift = icBitShift
    iLowShift = 0
    iRollOver = 0
    iHighMask = -1

  ' Initialize working string
    szTemp = ""

  ' Begin Decoding
    FOR iCounter = 1 TO LEN(szEncoded)

  ' Get next alphabet
        iChar = ASC(MID$(szEncoded, iCounter, 1))

  ' Get Decoded value
        iPtr = INSTR(szAlphabet, CHR$(iChar)) - 1

  ' Check if character is valid
        IF iPtr >= 0 THEN

  ' Char is valid, process it
            IF iShift = icBitShift THEN

  ' 1st char in block of 4, keep high part of character
                iRollOver = (iPtr * iShift) & icChopMask

  ' Reset masks for next character
                iHighMask = 0x030
                iLowShift = icStartMask
                iShift = icStartMask

            ELSE

  ' Start saving decoded character
                szTemp += CHR$(iRollOver | ((iPtr & iHighMask) / iLowShift))

  ' Calculate next mask and shift values
                iRollOver = (iPtr * iShift) & icChopMask
                iShift = iShift * icBitShift
                iHighMask = ((iHighMask / icBitShift) | 0x030)
                iLowShift = iLowShift / icBitShift

                IF iShift > 256 THEN
                    iShift = icBitShift
                    iLowShift = 0
                END IF
            END IF

        END IF
    NEXT iCounter

' return decoded string
    return szTemp
END sub



B64.glade:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Sat Sep  6 01:39:55 2008 -->
<glade-interface>
  <widget class="GtkWindow" id="window1">
    <property name="visible">True</property>
    <property name="border_width">6</property>
    <property name="title" translatable="yes">Emergence Basic Base64 Glade Demo</property>
    <property name="window_position">GTK_WIN_POS_CENTER</property>
    <signal name="destroy" handler="on_window1_destroy"/>
    <child>
      <widget class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <child>
          <widget class="GtkNotebook" id="notebook1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <child>
              <widget class="GtkFrame" id="frame1">
                <property name="visible">True</property>
                <property name="label_xalign">0</property>
                <property name="shadow_type">GTK_SHADOW_IN</property>
                <child>
                  <widget class="GtkAlignment" id="alignment1">
                    <property name="visible">True</property>
                    <property name="left_padding">12</property>
                    <child>
                      <widget class="GtkVBox" id="vbox2">
                        <property name="visible">True</property>
                        <property name="spacing">4</property>
                        <child>
                          <widget class="GtkEntry" id="txtEncode">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                          </widget>
                          <packing>
                            <property name="expand">False</property>
                          </packing>
                        </child>
                        <child>
                          <widget class="GtkHBox" id="hbox2">
                            <property name="height_request">36</property>
                            <property name="visible">True</property>
                            <child>
                              <widget class="GtkButton" id="btnEncode">
                                <property name="width_request">70</property>
                                <property name="height_request">22</property>
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                                <property name="receives_default">True</property>
                                <property name="label" translatable="yes">Encode</property>
                                <property name="response_id">0</property>
                                <signal name="clicked" handler="on_btnEncode_clicked"/>
                              </widget>
                              <packing>
                                <property name="expand">False</property>
                                <property name="padding">2</property>
                              </packing>
                            </child>
                            <child>
                              <widget class="GtkButton" id="btnEncodeClear">
                                <property name="width_request">70</property>
                                <property name="height_request">22</property>
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                                <property name="receives_default">True</property>
                                <property name="label" translatable="yes">Clear</property>
                                <property name="response_id">0</property>
                                <signal name="clicked" handler="on_btnEncodeClear_clicked"/>
                              </widget>
                              <packing>
                                <property name="expand">False</property>
                                <property name="position">1</property>
                              </packing>
                            </child>
                            <child>
                              <placeholder/>
                            </child>
                          </widget>
                          <packing>
                            <property name="expand">False</property>
                            <property name="fill">False</property>
                            <property name="position">1</property>
                          </packing>
                        </child>
                        <child>
                          <widget class="GtkScrolledWindow" id="scrolledwindow1">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                            <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
                            <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
                            <child>
                              <widget class="GtkTextView" id="textEncodeOutput">
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                                <property name="wrap_mode">GTK_WRAP_WORD_CHAR</property>
                                <property name="left_margin">1</property>
                                <property name="right_margin">1</property>
                              </widget>
                            </child>
                          </widget>
                          <packing>
                            <property name="padding">4</property>
                            <property name="position">2</property>
                          </packing>
                        </child>
                      </widget>
                    </child>
                  </widget>
                </child>
                <child>
                  <widget class="GtkLabel" id="label4">
                    <property name="visible">True</property>
                    <property name="use_markup">True</property>
                  </widget>
                  <packing>
                    <property name="type">label_item</property>
                  </packing>
                </child>
              </widget>
              <packing>
                <property name="tab_fill">False</property>
              </packing>
            </child>
            <child>
              <widget class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="label" translatable="yes">Encoder</property>
              </widget>
              <packing>
                <property name="type">tab</property>
                <property name="tab_fill">False</property>
              </packing>
            </child>
            <child>
              <widget class="GtkFrame" id="frame2">
                <property name="visible">True</property>
                <property name="label_xalign">0</property>
                <property name="shadow_type">GTK_SHADOW_IN</property>
                <child>
                  <widget class="GtkAlignment" id="alignment2">
                    <property name="visible">True</property>
                    <property name="left_padding">12</property>
                    <child>
                      <widget class="GtkVBox" id="vbox3">
                        <property name="visible">True</property>
                        <property name="spacing">4</property>
                        <child>
                          <widget class="GtkEntry" id="txtDecode">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                          </widget>
                          <packing>
                            <property name="expand">False</property>
                          </packing>
                        </child>
                        <child>
                          <widget class="GtkHBox" id="hbox3">
                            <property name="height_request">36</property>
                            <property name="visible">True</property>
                            <child>
                              <widget class="GtkButton" id="btnDecode">
                                <property name="width_request">70</property>
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                                <property name="receives_default">True</property>
                                <property name="label" translatable="yes">Decode</property>
                                <property name="response_id">0</property>
                                <signal name="clicked" handler="on_btnDecode_clicked"/>
                              </widget>
                              <packing>
                                <property name="expand">False</property>
                                <property name="fill">False</property>
                                <property name="padding">2</property>
                              </packing>
                            </child>
                            <child>
                              <widget class="GtkButton" id="btnDecodeClear">
                                <property name="width_request">70</property>
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                                <property name="receives_default">True</property>
                                <property name="label" translatable="yes">Clear</property>
                                <property name="response_id">0</property>
                                <signal name="clicked" handler="on_btnDecodeClear_clicked"/>
                              </widget>
                              <packing>
                                <property name="expand">False</property>
                                <property name="fill">False</property>
                                <property name="position">1</property>
                              </packing>
                            </child>
                            <child>
                              <placeholder/>
                            </child>
                          </widget>
                          <packing>
                            <property name="expand">False</property>
                            <property name="fill">False</property>
                            <property name="position">1</property>
                          </packing>
                        </child>
                        <child>
                          <widget class="GtkScrolledWindow" id="scrolledwindow2">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                            <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
                            <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
                            <child>
                              <widget class="GtkTextView" id="textDecodeOutput">
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                                <property name="wrap_mode">GTK_WRAP_WORD_CHAR</property>
                                <property name="left_margin">2</property>
                                <property name="right_margin">2</property>
                              </widget>
                            </child>
                          </widget>
                          <packing>
                            <property name="padding">4</property>
                            <property name="position">2</property>
                          </packing>
                        </child>
                      </widget>
                    </child>
                  </widget>
                </child>
                <child>
                  <widget class="GtkLabel" id="label5">
                    <property name="visible">True</property>
                    <property name="use_markup">True</property>
                  </widget>
                  <packing>
                    <property name="type">label_item</property>
                  </packing>
                </child>
              </widget>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <widget class="GtkLabel" id="label2">
                <property name="visible">True</property>
                <property name="label" translatable="yes">Decoder</property>
              </widget>
              <packing>
                <property name="type">tab</property>
                <property name="position">1</property>
                <property name="tab_fill">False</property>
              </packing>
            </child>
            <child>
              <widget class="GtkFrame" id="frame3">
                <property name="visible">True</property>
                <property name="label_xalign">0</property>
                <property name="shadow_type">GTK_SHADOW_IN</property>
                <child>
                  <widget class="GtkAlignment" id="alignment3">
                    <property name="visible">True</property>
                    <property name="left_padding">12</property>
                    <child>
                      <widget class="GtkVBox" id="vbox4">
                        <property name="visible">True</property>
                        <property name="spacing">4</property>
                        <child>
                          <widget class="GtkLabel" id="label7">
                            <property name="visible">True</property>
                            <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;This is a demo showing how
to use Emergence Basic with
the Glade Designer and
libGlade Under Linux.&lt;/b&gt;&lt;/big&gt;

&lt;b&gt;&lt;i&gt;Copyright 2008 Armando I. Rivera, Recursive Media Group&lt;/i&gt;&lt;/b&gt;</property>
                            <property name="use_markup">True</property>
                            <property name="justify">GTK_JUSTIFY_CENTER</property>
                          </widget>
                          <packing>
                            <property name="expand">False</property>
                            <property name="fill">False</property>
                            <property name="padding">56</property>
                          </packing>
                        </child>
                        <child>
                          <widget class="GtkHBox" id="hbox4">
                            <property name="height_request">45</property>
                            <property name="visible">True</property>
                            <child>
                              <placeholder/>
                            </child>
                            <child>
                              <placeholder/>
                            </child>
                            <child>
                              <placeholder/>
                            </child>
                          </widget>
                          <packing>
                            <property name="expand">False</property>
                            <property name="fill">False</property>
                            <property name="position">1</property>
                          </packing>
                        </child>
                        <child>
                          <placeholder/>
                        </child>
                      </widget>
                    </child>
                  </widget>
                </child>
                <child>
                  <widget class="GtkLabel" id="label6">
                    <property name="visible">True</property>
                    <property name="use_markup">True</property>
                  </widget>
                  <packing>
                    <property name="type">label_item</property>
                  </packing>
                </child>
              </widget>
              <packing>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <widget class="GtkLabel" id="label3">
                <property name="visible">True</property>
                <property name="label" translatable="yes">About</property>
              </widget>
              <packing>
                <property name="type">tab</property>
                <property name="position">2</property>
                <property name="tab_fill">False</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="padding">6</property>
          </packing>
        </child>
        <child>
          <widget class="GtkHBox" id="hbox1">
            <property name="visible">True</property>
            <child>
              <placeholder/>
            </child>
            <child>
              <widget class="GtkButton" id="btnExit">
                <property name="width_request">70</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="border_width">2</property>
                <property name="label" translatable="yes">Exit</property>
                <property name="response_id">0</property>
                <signal name="clicked" handler="on_window1_destroy"/>
              </widget>
              <packing>
                <property name="expand">False</property>
                <property name="pack_type">GTK_PACK_END</property>
                <property name="position">1</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="pack_type">GTK_PACK_END</property>
            <property name="position">1</property>
          </packing>
        </child>
      </widget>
    </child>
  </widget>
</glade-interface>


Script for use when compiling from a terminal:

#!/bin/bash
#**MODIFY THE PATH TO THE libebasic.a FILE!**

#Place this script somewhere in path (/usr/bin,/usr/local/bin,etc), call it what you want (I call mine "eb")
#Then, just "eb <name of source file>" WITHOUT the .eba extension or quotes


if [ -f $1.uselibs ]; then
  rm $1.uselibs
fi

if [ -f $1.eba ]; then
  ebparse $1.eba $1.o
  ld -e _gtkstart $1.o -o $1 ~/dev/ebasic/libebasic.a -ldl -lc -I /lib/ld-linux.so.2 $2 $3 $4 $5 `cat $1.uselibs`
  strip -s -R.comment $1
else
  echo "Unable to locate $1.eba.  Make sure you typed the name correctly..."
fi


Enjoy.....

AIR.
"Programming is like Poetry. Sometimes the words just escape you..."
-me, to my manager.

http://www.recursivemedia.net

Ionic Wind Support Team

Hi Armando,
Just a couple of points...

You don't need to call gtk_init as it is done for you by the entry point _gtkstart, otherwise you are actually calling it twice.  Not sure what the side effects of that will be.

Similarly if you use the built in functionality of WaitUntil then you also don't need gtk_main and gtk_main_end,  but it is fine either way.

Nice example in any case  :D

Paul.
Ionic Wind Support Team

Allan

Thank you very much for the Glade example AIR.

Allan

Allan

September 06, 2008, 05:42:04 PM #3 Last Edit: September 06, 2008, 06:35:42 PM by Allan
Hi AIR

I have it up and running after having to get glade.dev installed.

When I run the program it comes up fine and the Encode works fine. But the Decode does not work out.

Just to make sure I am using it correctly.

1. Start prog and enter my Name in the Encode Edit box
2. Click Encode button
3. Copy the Encoded text from the Text View
4. Click Clear button
5. Click the Decode Tab.
6. Paste in the Encoded text to the Decode Edit box.
7. Click Decode button

Quotebpak@bpak-desktop:~/EBasic_Linux/AIR$ dir
B64.glade    base64_demo.asm  base64_demo.o
base64_demo  base64_demo.eba  base64_demo.uselibs
bpak@bpak-desktop:~/EBasic_Linux/AIR$ ./base64_demo
Segmentation fault (core dumped)
bpak@bpak-desktop:~/EBasic_Linux/AIR$

Segment fault (core dumped) suggests a problem with....?

Allan

Armando Rivera

Hmmmmm.  Not sure, because I'm not getting that here.

Let me look into it some more, and I'll get back to you....

AIR.
"Programming is like Poetry. Sometimes the words just escape you..."
-me, to my manager.

http://www.recursivemedia.net

Armando Rivera

It may have something to do with not checking if the encoded/decoded string is within the "safe" ascii range.

In the start_process sub, try replacing whats between the end of the select block and the "end if" at the end of the sub with:

    '~ GET THE HANDLE TO THE GTKTEXVIEW'S GTKTEXTBUFFER
    g_object_get(textviewHnd,"buffer",&textbuffer,0)
   
    '~ GET THE ASC VALUE OF THE FIRST CHARACTER IN THE
    '~ RETURNED STRING
    int first_char:first_char= asc(encoded_string)   

    '~ FILTER TO CHECK IF WITHIN SAFE ASCII RANGE
    if ((first_char > 31) and (first_char<128)) then

    '~SET THE GTKTEXTBUFFER'S CONTENTS TO THE ENCODED STRING
        g_object_set(textbuffer,"text",encoded_string,0)
    else
    '~ NOT IN SAFE RANGE. NOTIFY USER
        g_object_set(textbuffer,"text","** Invalid Entry **",0)
    end if

    '~ FREE UP MEMORY ALLOCATED TO THE textbuffer OBJECT
    g_object_unref(textbuffer)


Which distro are you using, and what version of GTK is installed?

AIR.
"Programming is like Poetry. Sometimes the words just escape you..."
-me, to my manager.

http://www.recursivemedia.net

Allan

September 06, 2008, 08:39:31 PM #6 Last Edit: September 06, 2008, 08:45:08 PM by Allan
Ubuntu Fiesty 7.04 with latest updates.

GTK version is 2 something. Dont know how to find this out as they have numbers all over the place.

They have some things mentioned as version 2.10.11 and lots of different combinations for various GTK files. But I guess this is the version.

libgtk2.0-dev  is 2.10.11

Could you indicate the file name I would look for in the Synaptic Package Manger please if that is not the one?

I thought this system automatically updated??

I will try that change in the prog.

Thanks....
Allan

EDIT

Still comes up with the same error message.
Quotebpak@bpak-desktop:~/EBasic_Linux/AIR$ eb base64_demo
bpak@bpak-desktop:~/EBasic_Linux/AIR$ ./base64_demo
Segmentation fault (core dumped)
bpak@bpak-desktop:~/EBasic_Linux/AIR$

Allan

Armando Rivera

September 06, 2008, 09:18:41 PM #7 Last Edit: September 06, 2008, 11:01:27 PM by Armando Rivera
I don't think the change is gonna help.

It looks like a GLib Version difference, not GTK.  My mistake.

Base64 Encoding/Decoding support was added as of Glib 2.12.  If you don't have that version, that's the likely cause of the segfault.

So, what can we do?

Create Native Base64 Encoding/Decoding routines.

I have an Encode routine that I ported from some ancient code I came across, but I haven't worked out a Decode routine yet:

*EDIT*  Encode/Decode routines have been redone using Native code.  See the first post for updated example.

AIR.
"Programming is like Poetry. Sometimes the words just escape you..."
-me, to my manager.

http://www.recursivemedia.net

Allan

Looking through the packages under Libraries Development there is libglib2.0-dev  2.12.11.0   ubuntu1

That would be the correct one?

Allan

Armando Rivera

September 06, 2008, 10:49:20 PM #9 Last Edit: September 06, 2008, 11:02:45 PM by Armando Rivera
Yes, that should be the one.

You raise an interesting point, though:  How to address end-users that DON'T have the latest libs installed.

I think trying to implement as much as possible in a native fashion is the answer.

I've worked out native routines to both encode and decode Base64 strings, and will be updating the original post shortly.  ;D

**EDIT** Original post has been updated.

AIR.
"Programming is like Poetry. Sometimes the words just escape you..."
-me, to my manager.

http://www.recursivemedia.net

Allan

Hi AIR

I found the problem.

After finding it was in libglib and not GTK I managed to install docs for it and in DevHelp could search for the g_base64_Decode

It showed that it returned the gsize (32 bit integer) in the variable u used  txt_len

So I changed it from a pointer to an INT

INT txt_len

and change the call:
encoded_string=g_base64_decode(source_string,&txt_len)

Compiled it with   eb

and it now works fine.

Thanks for the help and LOOK forward to more examples to work with.

Thanks again AIR

Allan

Allan

QuoteYou raise an interesting point, though:  How to address end-users that DON'T have the latest libs installed.

I think trying to implement as much as possible in a native fashion is the answer.

I like the idea of native fashion indeed.  Though I think I was reading somewhere about making dpkg (Installation Package) and that you can declare in it the libs needed and it will make/let the user get those files if needed.

Cant remember exactly but it was something like that.

Allan



Armando Rivera

Quote from: Allan on September 06, 2008, 11:05:14 PM
Hi AIR

I found the problem.

After finding it was in libglib and not GTK I managed to install docs for it and in DevHelp could search for the g_base64_Decode

It showed that it returned the gsize (32 bit integer) in the variable u used  txt_len

So I changed it from a pointer to an INT


Good catch, Allan!.

This is why I try to share my code, because after staring at it for what seems like an eternity a fresh set of eyes sees things that I can't anymore. ;)


QuoteThanks for the help and LOOK forward to more examples to work with.

;D You know my track record.....I'm still getting up to speed with what the native gui capabilities are, so the next thing I'm working on will be using (mostly) Gtk Api calls.

Is there a comprehensive list of what's implemented in the current Linux version?  For example, I tried ENUM and it didn't work.  @GROUPBOX didn't display anything either, but didn't cause any errors compiling or executing...

AIR.

"Programming is like Poetry. Sometimes the words just escape you..."
-me, to my manager.

http://www.recursivemedia.net

Ionic Wind Support Team

Air,
There is a 1 to 1 correspondence for most of the controls from the windows to linux versions.  The point is to be able to compile your code on both compilers without much changes.  Off the top of my head, without booting into linux, button, checkbox, scrollbars, edit, multi line edit, combobox, and list box are working. Radiobuttons were next, have to simulate automatic grouping like Windows does.

There are some linux specific functions like GetControlWidget which returns a pointer to the GtkWidget based on the Emergence control ID.  Functions just like GetControlHandle does on the windows version.  Which would propbably come in handy for you. GetControlWidget understands container hierarchy.

There are container controls as well built in.  @HPANED and @VPANED for example.  Which I use for things like tinyide. 

The example programs are meant to give a general idea of what is working so far.

The Emergence Window simulates a window from the Microsoft OS's.  It doesn't automatically scale or position controls that are placed in it.  But you can achieve the same functionality as Gtk using a container control and sizing that container when your handler receives a @IDSIZE message. 

The other linux specific function that you might find useful is CreateControl, which creates a control without adding it to a window, it returns a pointer to the base widget used to construct the control in question.  You can also create any widget using gtk functions, and make it an Emergence control by setting a few object data properties. 

"EBIDENT" is the numeric identifier
"EBTYPE" controls how functions like SetFont, SetControlColor, etc work.
"EBSTYLE" is the style bits used when creating the control.

If your control is a compound widget, such as gtk_scrollable with some other control being scrolled, then call it a @button so SetFont will use gtk_bin_get_child.  If it isn't a compound widget then give it a non existant type like 99999 as there are default cases.

In any event here is some of the creation code for tinyide so you can see how I combine native control functionality with GTK api functions.


openwindow win,0,0,640,400,@SIZE|@MINBOX|@MAXBOX|@MAXIMIZED|@NOAUTODRAW,0,"Emergence BASIC Tiny IDE 0.5",&mainwindow
getclientsize win,left,top,width,height
control win,@VPANED,"",left,top,width,height,0,100
pointer pControl,pControl2,pNotebook,pDocument
pControl2 = GetControlWidget(win,100)
if pControl2
pNotebook = CreateControl(@NOTEBOOK,"",0,0,640,100,0,200)
gtk_paned_pack1(pControl2,pNotebook,true,false)
gtk_notebook_set_scrollable(pNotebook,TRUE)
pControl = CreateControl(@HPANED,"",0,0,0,0,0,300)
gtk_paned_pack2(pControl2,pControl,false,false)
pControl2 = CreateControl(@EDIT,"",0,0,320,100,@CTEDITMULTI|@HSCROLL|@VSCROLL,400)
gtk_text_view_set_editable(gtk_bin_get_child(pControl2),false)
gtk_scrolled_window_set_policy(pControl2,1,1)
gtk_paned_add1(pControl,pControl2)
NewDocument()
endif



sub NewDocument(),int
pointer pControl
'
pointer pScrollWindow:pScrollWindow = gtk_scrolled_window_new(NULL,NULL)
pControl = gtk_source_view_new()
gtk_container_add(pScrollWindow,pControl)
g_object_set_data(pScrollWindow,"EBIDENT",base_edit_id)
g_object_set_data(pScrollWindow,"EBTYPE",@EDIT)
g_object_set_data(pScrollWindow,"EBSTYLE",@CTEDITMULTI|@HSCROLL|@VSCROLL)
gtk_source_view_set_show_line_numbers(pControl,true)
gtk_source_view_set_show_line_markers(pControl,true)
gtk_source_view_set_indent_on_tab(pControl,true)
gtk_source_view_set_tabs_width(pControl,4)
gtk_widget_show_all(pScrollWindow)
pControl = pScrollWindow

pDocument = NEW(document,1)
#<document>pDocument.edit_id = base_edit_id
g_object_set_data(pControl,"document",pDocument+0)
gtk_widget_show(pControl)
page = gtk_notebook_append_page(pNotebook,pControl,NULL)
CreatePageTab(page,"Untitled" + ltrim$(str$(current_untitled)))
setfont win,"Sans",11,400,0,base_edit_id
current_untitled++
base_edit_id++
return page
endsub

SUB CreatePageTab(int page,string title)
pointer pBook,pPage,pTab,pClose,pLabel,pImage,hfont
pBook = GetControlWidget(win,200)
if pBook
pPage = gtk_notebook_get_nth_page(pBook,page)
pTab = CreateControl(@HBOX,"",0,0,0,0,0,3000)
pClose = CreateControl(@BUTTON,"",0,0,0,0,0,1000)
pImage = gtk_image_new()
gtk_image_set_from_stock(pImage,"gtk-close",1)
gtk_button_set_relief(pClose,2)
gtk_button_set_image(pClose,pImage)
g_signal_connect_data(pClose,"clicked",&CloseTabClicked,pPage,NULL,0)
gtk_box_pack_end(pTab,pClose,false,false,0)
pLabel = CreateControl(@STATIC,title,0,0,0,0,0,2000)
hfont = pango_font_description_from_string("Sans 10")
gtk_widget_modify_font(pLabel,hfont)
pango_font_description_free(hfont)
gtk_box_pack_start(pTab,pLabel,true,true,0)
gtk_notebook_set_tab_label(pBook,pPage,pTab)
endif
ENDSUB


Paul.
Ionic Wind Support Team

Armando Rivera

Thanks, Paul.

I actually have looked over the source to tinyide and did have some questions, which you've answered.

Thanks again for the info, it will definitely come in handy.


AIR.

"Programming is like Poetry. Sometimes the words just escape you..."
-me, to my manager.

http://www.recursivemedia.net

Allan

Hi AIR

QuoteThis is why I try to share my code, because after staring at it for what seems like an eternity a fresh set of eyes sees things that I can't anymore

I am not too cluey about Linux and its API yet but hopefully my experience with programming in Emergence may help a bit.

Looks like a lot of pointer in the GTK API.

QuoteYou know my track record.....I'm still getting up to speed with what the native gui capabilities are, so the next thing I'm working on will be using (mostly) Gtk Api calls.

Look forward to it. I dont have the Source so leave it to the experts  ::)