In addition to my GTK4 minimal example (https://sourceforge.net/p/gnucobol/discussion/cobol/thread/170a0e64d4/#33e1), here is a more comprehensive program that contains everything you need to develop an application:
Enter some data
Verify the input
Process the data
Present the result
It also uses some CSS styles to give the application a more appealing form.
See the screen shots.
Here's the program code:
>>SOURCEFREE*>DocumentationforGTK4:https://docs.gtk.org/gtk4/getting_started.html*>Compilewith:*>cobc--static-x`pkg-config--libsgtk4`easterdate4.cbl*>*>License:MITLicense*>--------------------*>*>Copyright2025KlausSiebke*>*>Permissionisherebygranted,freeofcharge,toanypersonobtainingacopy*>ofthissoftwareandassociateddocumentationfiles(the“Software”),todeal*>intheSoftwarewithoutrestriction,includingwithoutlimitationtherights*>touse,copy,modify,merge,publish,distribute,sublicense,and/orsell*>copiesoftheSoftware,andtopermitpersonstowhomtheSoftwareis*>furnishedtodoso,subjecttothefollowingconditions:*>*>Theabovecopyrightnoticeandthispermissionnoticeshallbeincludedinall*>copiesorsubstantialportionsoftheSoftware.*>*>THESOFTWAREISPROVIDED“ASIS”,WITHOUTWARRANTYOFANYKIND,EXPRESSOR*>IMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOFMERCHANTABILITY,*>FITNESSFORAPARTICULARPURPOSEANDNONINFRINGEMENT.INNOEVENTSHALLTHE*>AUTHORSORCOPYRIGHTHOLDERSBELIABLEFORANYCLAIM,DAMAGESOROTHER*>LIABILITY,WHETHERINANACTIONOFCONTRACT,TORTOROTHERWISE,ARISINGFROM,*>OUTOFORINCONNECTIONWITHTHESOFTWAREORTHEUSEOROTHERDEALINGSIN*>THESOFTWARE.*>identificationdivision.program-id.easterdate4.environmentdivision.configurationsection.SPECIAL-NAMES.CALL-CONVENTION0ISSTANDARDC.repository.functionallintrinsic.input-outputsection.file-control.datadivision.filesection.working-storagesection.*>****************************************************************01resultusagebinary-long.01result-booleanusagebinary-longsync.01gtk-xmlfileusagepointer.01gtk-window-mainusagepointer.01gtk-entry-bufferusagepointer.01gtk-entry-yearusagepointer.01gtk-entry-year-valueusagepointer.01gtk-lbl-message1usagepointer.01gtk-lbl-message2usagepointer.01gtk-notebookusagepointer.01gtk-builderusagepointer.01gtk-appusagepointer.01gdk-displayusagepointer.01gdk-monitorusagepointer.01gdk-surfaceusagepointer.01gtk-nativeusagepointer.01gtk-widgetusagepointer.01gtk-cssproviderusagepointer.01icon_themeusagepointer.01g-connect-idusagebinary-longunsignedsync.01gtk-callbackprogram-pointer.01gtk-buttonusagepointer.01css-priorityusagebinary-long.01window-widthusagebinary-long.01window-heightusagebinary-long.01pidpic9(5)value00000.01ipidusagebinary-long.01easter-year-xpicx(4).01easter-yearredefineseaster-year-xpic9(4).01easter-year-lenpic9.01wLanguagepicx(16)valuespace.01wUserNamepicx(16)valuespace.*>FieldsforEasterDatecalculation01ACCEPT-YEARPIC9(08).01WORKING-FIELDSCOMP.05TGT-YEARPICS9(08).05GOLDEN-NUMBERPICS9(08).05TGT-CENTURYPICS9(08).05LEAP-YEAR-CRCTNPICS9(08).05MOON-SYNC-CRCTNPICS9(08).05FIRST-SUNDAYPICS9(08).05EPACTPICS9(08).05FULL-MOONPICS9(08).05EASTER-SUNDAYPICS9(08).01DISPLAY-FIELDS.05TGT-YEAR-DSPPICZ(08)-.05EASTER-MONTHPICX(06).05EASTER-SUNDAY-DSPPICZ(02)-.01msgdisplay.05msg-txtPICX(20)VALUE"Easter Date is".05msg-monthPICX(06).05msg-dayPICZZ.05fillerPICX(01)VALUEx"00".01ws-message.05msg-textPICX(40).05fillerPICX(01)VALUEx"00".linkagesection.*>****************************************************************01gtk-applusagepointer.01gtk-winusagepointer.01gtk-datusagepointer.01gdk-rectangleusagepointer.05gkd-rect-xusagebinary-longunsignedsync.05gkd-rect-yusagebinary-longunsignedsync.05gkd-rect-widthusagebinary-longunsignedsync.05gkd-rect-heightusagebinary-longunsignedsync.proceduredivision.*>******************************************************************>Mainprogram*>******************************************************************>******************************************************************>getthepidcall"C$GETPID"returningipidmoveipidtopid*>display"pid:"pidend-displayACCEPTwUserNameFROMUSERNAMEend-acceptACCEPTwLanguageFROMENVIRONMENT"LANG"END-ACCEPT*>initGtkcall"gtk_init_check"usingbyvalue0byreferencenullreturningresultend-callifresultnotequal1*>1:TRUEdisplay"Gtk could not be initialized - Program terminated"end-displaystoprunend-if*>getreferencetoappcall"gtk_application_new"usingbycontentz"com.siebke.easterdate"byvalue0returninggtk-append-callsetgtk-callbacktoentry"activate_my_app"call"g_signal_connect_data"usingbyvaluegtk-appbycontentz"activate"*>withinlineZstringbyvaluegtk-callback*>functioncallbackpointerbyreferenceNULLreturningg-connect-idend-callcall"g_application_run"usingbyvaluegtk-appbyvalue0byreferencenullreturningresultend-call*>SomethingterminatedtheGTKmainloop:wrapup*>stoprun.*>doesnotworkhere...EXITPROGRAM.*>...useEXITPROGRAMinstead*>******************************************************************>Callbacks*>******************************************************************>-----------------------------------------------------ENTRYSTANDARDC"activate_my_app"USINGbyreferencegtk-applbyvaluegtk-dat.*>getreferencetodefaultdisplaycall"gdk_display_get_default"returninggdk-displayend-callcall"gtk_icon_theme_get_for_display"usingbyvaluegdk-displayreturningicon_themeend-callcall"gtk_icon_theme_add_search_path"usingbyvalueicon_theme*>bycontentz"/storage/source/gnucobol/gtk_4/"bycontentz"."end-call*>loadthedefaulticonforthewindowscall"gtk_window_set_default_icon_name"usingbycontentz"Easter_icon"end-call*>*************>CSSHandling*>************call"gtk_css_provider_new"returninggtk-cssproviderend-callcall"gtk_css_provider_load_from_path"usingbyvaluegtk-cssproviderbycontentz"guistyle.css"byreferencenullend-callcall"gdk_display_get_default"returninggdk-displayend-callmove600tocss-prioritycall"gtk_style_context_add_provider_for_display"usingbyvaluegdk-displaybyvaluegtk-cssproviderbyvaluecss-priorityend-call*>loadthexmluifilewiththescreenlayoutcall"gtk_builder_new_from_file"usingbycontentz"frmeaster.ui"returninggtk-builderend-call*>getreferencetomainwindowscall"gtk_builder_get_object"usingbyvaluegtk-builderbycontentz"winEaster"returninggtk-window-mainend-call*>getreferencetoinputfieldforeasteryearcall"gtk_builder_get_object"usingbyvaluegtk-builderbycontentz"entYEARE"returninggtk-entry-yearend-call*>getreferencetomessagelabelonfirsttabcall"gtk_builder_get_object"usingbyvaluegtk-builderbycontentz"lblMESS1"returninggtk-lbl-message1end-call*>getreferencetomessagelabelonsecondtabcall"gtk_builder_get_object"usingbyvaluegtk-builderbycontentz"lblMESS2"returninggtk-lbl-message2end-call*>getreferencetonotebookcontainingthescreenscall"gtk_builder_get_object"usingbyvaluegtk-builderbycontentz"nbkSCRNS"returninggtk-notebookend-call*>getreferencetobackbuttoncall"gtk_builder_get_object"usingbyvaluegtk-builderbycontentz"btnBack"returninggtk-buttonend-callcall"g_object_unref"usingbyvaluegtk-builderend-callcall"gtk_window_set_application"usingbyvaluegtk-window-mainbyreferencegtk-applend-callcall"gtk_window_present"usingbyvaluegtk-window-mainend-callgoback.*>-----------------------------------------------------ENTRYSTANDARDC"on_btnCalc_clicked"USINGbyvaluegtk-winbyvaluegtk-dat.call"gtk_label_set_text"usingbyvaluegtk-lbl-message1bycontentz" "end-callcall"gtk_editable_get_text"usingbyvaluegtk-entry-yearreturninggtk-entry-year-valueend-callmovecontent-of(gtk-entry-year-value)toeaster-year-xmoveLENGTH(content-of(gtk-entry-year-value))toeaster-year-lenifeaster-year-x(1:easter-year-len)ISNUMERICifeaster-yearlessthan1583call"gtk_label_set_text"usingbyvaluegtk-lbl-message1bycontentz"Error: Year must be 1583 or later"end-callelse*>CalculateEasterDatePERFORMCalcEasterDatethruCalcEasterDateExcall"gtk_label_set_text"usingbyvaluegtk-lbl-message2bycontentws-message*>msgdisplayend-callcall"gtk_notebook_set_current_page"usingbyvaluegtk-notebookbyvalue1*>1end-callcall"gtk_widget_has_default"usingbyvaluegtk-buttonend-callelsecall"gtk_label_set_text"usingbyvaluegtk-lbl-message1bycontentz"Error: Year is not numeric"end-callend-ifgoback.*>-----------------------------------------------------ENTRYSTANDARDC"on_btnQuit_clicked"USINGbyvaluegtk-winbyvaluegtk-dat.call"gtk_window_destroy"usingbyvaluegtk-window-mainend-callgoback.*>-----------------------------------------------------ENTRYSTANDARDC"on_btnBack_clicked"USINGbyvaluegtk-winbyvaluegtk-dat.call"gtk_label_set_text"usingbyvaluegtk-lbl-message1bycontentz" "end-callcall"gtk_widget_grab_focus"usingbyvaluegtk-entry-yearend-callcall"gtk_editable_set_text"usingbyvaluegtk-entry-yearbycontentX"00"*>emptythefieldend-callcall"gtk_notebook_set_current_page"usingbyvaluegtk-notebookbyvalue0end-callgoback.*>******************************************************************>Subroutines*>*****************************************************************CalcEasterDate.*>-----------------------------------------------------------------*>Thisroutinecalculatesthedateofeasterforyearsinthe*>Gregoriancalendar.It's a port of the Donald Knuth Algorithm*>publishedinVolume1of"The Art Of Programming".*>Author:PaulChandler,March2013*>Source:https://gnucobol.sourceforge.io/faq/index.html#a-real-cobol-computus*>-----------------------------------------------------------------MOVEeaster-yearTOACCEPT-YEARMOVEACCEPT-YEARTOTGT-YEARTGT-YEAR-DSPCOMPUTEGOLDEN-NUMBER=FUNCTIONMOD(TGT-YEAR,19)+1COMPUTETGT-CENTURY=(TGT-YEAR/100)+1COMPUTELEAP-YEAR-CRCTN=(3*TGT-CENTURY/4)-12COMPUTEMOON-SYNC-CRCTN=((8*TGT-CENTURY+5)/25)-5COMPUTEFIRST-SUNDAY=(5*TGT-YEAR/4)-LEAP-YEAR-CRCTN-10*>*>TOMAKETHEEPACTCALCULATIONMOREREADABLE,*>THECOMPUTATIONWILLBEDONEINSTAGES.*>*>*>STAGE#1: GET THE RAW NUMBER..... *>COMPUTEEPACT=(11*GOLDEN-NUMBER)+20+MOON-SYNC-CRCTN-LEAP-YEAR-CRCTN*>*>STAGE#2: GET THE MOD 30 VALUE... *>COMPUTEEPACT=FUNCTIONMOD(EPACT,30)*>*>STAGE#3: TO ENSURE THAT EPACT IS A POSITIVE NBR, *>ADD30ANDMOD30AGAIN.ADD30TOEPACTCOMPUTEEPACT=FUNCTIONMOD(EPACT,30)*>*>ADJUSTFORYEARSWHENORTHODOXDIFFERS*>IF(EPACT=25ANDGOLDEN-NUMBER>11)OR(EPACT=24)ADD1TOEPACTEND-IF*>*>NEXTTWOSTATEMENTSFINDFIRSTFULLMOONAFTERMAR.21*>SUBTRACTEPACTFROM44GIVINGFULL-MOONIFEPACT>23ADD30TOFULL-MOONEND-IF*>*>ADVANCESUNDAYTOTHEFIRSTSUNDAYAFTERFULLMOON*>COMPUTEEASTER-SUNDAY=FULL-MOON+7-(FUNCTIONMOD((FIRST-SUNDAY+FULL-MOON),7))*>*>IFEASTER-SUNDAY>31,EASTERISINAPRIL-MOVETHE*>MONTHTOAPRILANDSUBTRACT31FROMTHEMONTH.*>OTHERWISEEASTERISINMARCH,USETHEDAYASIS.*>IFEASTER-SUNDAY>31MOVE'April'TOmsg-month*>EASTER-MONTHSUBTRACT31FROMEASTER-SUNDAYELSEMOVE'March'TOmsg-month*>EASTER-MONTHEND-IFMOVEEASTER-SUNDAYTOmsg-day*>EASTER-SUNDAY-DSPmoveconcatenate(trim(msg-txt)" "msg-month" "msg-day" "easter-year)tomsg-textcontinue.CalcEasterDateEx.exit.
Because some binary files (images) are needed, I have added a zip file with the complete directory structure.
Just unpack it and compile it with
Klaus, that would be a good entry for the examples in the contrib repo (same for the simple example if it isn't in yet). Would you mind adding a license now and upload it there? Maybe you prefer someone else to do the commit?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Simon, sorry for the late reply - too much other work on my desk ....
I have added a license in both, the simple example and the easterdate calculation.
Not sure, as I am not a lawyer, but I think that the MIT License grants the greatest freedom for everyone.
I am not familiar with the contrib repo. Could someone else move it to the right place?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In addition to my GTK4 minimal example (https://sourceforge.net/p/gnucobol/discussion/cobol/thread/170a0e64d4/#33e1), here is a more comprehensive program that contains everything you need to develop an application:
It also uses some CSS styles to give the application a more appealing form.
See the screen shots.
Here's the program code:
Because some binary files (images) are needed, I have added a zip file with the complete directory structure.
Just unpack it and compile it with
cobc --static -x
pkg-config --libs gtk4
easterdate4.cblI have tested it under Fedora 40 and Debian 12.
Last edit: Klaus Siebke 2025-05-27
Klaus, that would be a good entry for the examples in the contrib repo (same for the simple example if it isn't in yet). Would you mind adding a license now and upload it there? Maybe you prefer someone else to do the commit?
Simon, sorry for the late reply - too much other work on my desk ....
I have added a license in both, the simple example and the easterdate calculation.
Not sure, as I am not a lawyer, but I think that the MIT License grants the greatest freedom for everyone.
I am not familiar with the contrib repo. Could someone else move it to the right place?
Here are the screenshots ...
Thanks to share...
Very useful...!