લહીઆઓ પુસ્તક લખતાં લખતાં સહેજ ઊઠવું હોય અથવા લખવાનું તે દિવસ માટે કે અમુક વખત માટે બંધ કરવું હોય તો સ અક્ષર ઉપર અટકતા નથી. કારણ કે તેઓ માને છે કે, સ સંદેહ ધરે.
Cogito, ergo sum // I think, therefore I am.
મહેંદી તે વાવી માળવે ને એનો રંગ ગયો ગુજરાત રે
May 20, 2026હશે, એને વધુ જરૂર હશે!
May 16, 2026મહેશે બધાંને કીધું કે, "એવું હોય તો હું અને કાનો અહીં ઉભા રહી તમારા ચપ્પલનું અને સામાનનું ધ્યાન રાખીશું, તમે દર્શન કરી આવો. તમે પાછા આવીને આગળનું જે હોય એ કરજો અને હું ને કાનો પછી દર્શન કરી આવશું."
ઘરના બધાં સભ્યો પોત-પોતાનાં ચપ્પલ મૂકતા હતા ત્યાં મહેશની પત્ની પણ ભાવિકા મહેશ પાસે આવી ચપ્પલ મૂકતી હતી. એને જોઈને મહેશે કીધું, "આને કુદરતની કરામત કેવાય, જે દિપકભાઈ પહેલા ભગવાનમાં માનતાં ન હતાં એ આજે દીકરીની બાધા પુરી કરવા બળિયા બાપજીના મંદિર આવ્યા છે" ભાવિકાને એ વાત કરતાં સમાનની સાચવણીમાં વધુ રસ હતો એટલે એને ટૂંકમાં જવાબ આપતા, "હોય, માં-બાપ સંતાન માટે બધું કરવાં તૈયાર થઈ જાય અને..." વાક્ય પૂરું નથી થયું ત્યાં બાજુમાં સિક્યોરિટીવાળા દાદા વાત ઉપાડતાં બોલ્યાં, "આને જ કુદરતનો ખેલ કે'વાય ભલભલાંને આ ખેલ રમવો પડે જેમ રમાડે એમ" પણ ભાવિકાને દર્શન કરવાં જવાની ઉતાવળ હતી એટલે એને એનું ચાલુ રાખ્યું કે, "...અને આ બધાં સામાનનું ધ્યાન રાખજો, આઘા પાછા થતાં નહીં, અમે આવી પછી જ ગુલ્લી મારજો" અને ભાવિકા બધા લોકો સાથે દર્શન કરવાં ગઈ.
કાનાને સિગરેટ પીવાની ઈચ્છા થઇ એટલે એને ગુલ્લી મારી. મહેશને બીજું કાંઈ કામ ન હતું એટલે એને પેલા દાદા પાસે જઈને વાતનો છેડો પકડતા વાત આગળ ચલાવી, "કુદરતનો ખેલ બધાને રમાડે, તમને તો મારા કરતા વધુ અનુભવ હશે, એકાદ અનુભવ તો કહો".
દાદાની આંખમાં ચમક આવી, આજે ઘણાં સમયે કોઈ એની પાસે આવ્યું છે, અને સંભાળવા માગે છે, અને એ પણ અનુભવ. દાદાએ આંગળી ચીંધી એક દરવાજાને ટેકે બેસેલા બીજા દાદાને દેખાડી વાત ઉપાડી, "એ ખીમો, મારો કુટુંબી ભૈ થાય, મારી ભેગું આયા જ નોકરી કરતો હતો. હવે એને સારું નથી રેતુ એટલે નોકરી નથી રૈ, ત્યાં રોજ બેસે. એનો સમય હતો ત્યારે આયા મંદિરનાં દરવાજા પાસે છાસ-પાણી વેચવાવાળા પાસેથી ઘણું પડાવીને ખાધું. એ દુઃખિયા આને જ્યાં સુધી લાંચમાં છાસની ૩-૪ કોથળી આપે નહિ ત્યાં સુધી આ એમણે મંદિરના દરવાજા પાસે છાસ વેચવાના દે".
"૩-૪ છાશની કોથળી જોતી પીવામાં".
"નારે રે નાં, એક છાશની કોથળી શું અડધી પણ બહુ કે'વાય, આતો શરૂઆતમાં એક માગતો, પછી ધીમે ધીમે લાગ્યું કે આ લોકો મારુ કંઈ કરી નથી શકવાનાં એટલે વધુ નફ્ફટાઈ ચાલુ કરી પેલાં બે માંગવાની ચાલુ કરી, પછી ત્રણ, પછી તો ચાર ને પાંચ પણ, પૂનમના દિવસોમાં તો પૈસા પણ પડાવી લેતો."
"લોભ જાગ્યો આતો"
"મહેનત નથી કરવાની ને!"
"પછી?"
"એકની પાસેથી છાશ પડાવતો, બીજા પાસેથી પાણી, ત્રીજા પાસેથી રસ તો ચોથા પાસેથી પૈસા. આજ એની નોકરી થઇ ગઈ હતી. બપોર અને સાંજ પડે એટલે ઘરે બૈરી છોકરાં ને આપી આવતો. કોઈક વાર જો પાણીપુરી વાળો મળી જાય તો એનું પણ કરી નાખતો. રોજનું રોજ આવવા માંડ્યું એટલે ઘરનાને પણ આ ખાવાની ટેવ પડી ગઈ. કોઈક દિવસ જો ખાલી હાથે જાય તો ઘરનાં ટોણા મારે."
દાદા ક્યાંક દૂર આકાશમાં જોતા હોય એમ વાત ચાલુ રાખી, "મને એ દિવસ બરોબર યાદ છે, આ બાજુવાળા પરાની સતુડોશીએ છાસ વેચવાનું ચાલુ કર્યું હતું, એનો છોકરો થોડા સમય પેલા દારૂમાં પતી ગયો હતો એટલે, કમાવા માટે છાસ વેચવા આવી હતી, ૭ કોથળી હતી અને આને ૪ એની પાસેથી પડાવી લીધી, ૩ વેચીને ખોટ ખાઈને ગઈ. મેં ના પાડી હતી કે ડોસીને હેરાન ના કર જવાદે એને પણ ના માન્યો અને ૪ કોથળી લઈને ઘરે ચાલતો થયો."
"ડોસી મેં કીધું કે તમારે આપવી જ ન હતી, પણ ડોસીની આંખ ઊંડી ઊતરી ગઈ હતી, જતાં જતા કે'તી ગઈ, હશે એને વધુ જરૂર હશે મારાં કરતાં. ડોસી પછી થી કોઈ દિવસ છાસ વેચવાના ના દેખાણી".
"આને છેલ્લા ૫ વરસથી પેટની બીમારી થઇ ગઈ છે, ૩-૪ ડોક્ટરને બતાવ્યું. પણ બીમારી પકડાતી નથી. ક્યાંથી પકડાય! કોકની હાય થોડી રિપોર્ટમાં આવે. ઘરના એ ના પાડી દીધી કે હવે બીજા ડોક્ટર ને બતાવવાનાં પૈસા નથી. બીમારી પણ એવી થઈ છે આને, કે કંઈક ખાય એટલે તરત જ બારું. કા ઝાળા કા ઉલટી. આ બધા પાસેથી રોજ પડાવીને ખાય એટલે ઘરે જઈને ઝાળા ઊલટી કરતો. બહુ વધી ગયું એટલે ઘરનાએ કાઢી મુક્યો. નોકરી કરવા જેટલી તાકાત નથી રહી. કઈ ખાય નહિ તો સારું રે. થોડું પાણી ને પ્રવાહી થી ચલાવે છે. પેલા જરૂર ન હતી તો બહુ લઈ લીધું, અને હવે જરૂર છે તો કોઈ આપતું નથી, મળતું નથી. કુદરતના ચોપડામાં બધો હિસાબ છે વ્યાજ સાથે."
વાકછલ
May 08, 2026વાસુદેવ કહે. 'સંજય, તું દૂત છે એટલે એમના પક્ષની જ તું વાત કરે તેમાં તારો દોષ નથી. પણ વાકછલ ઈષ્ટ નથી. પ્રશ્ન જ્ઞાની-અજ્ઞાનીનો નથી. ન્યાય-અન્યાયનો છે. અજ્ઞાની અન્યાય કરે તેથી દંડમાંથી બચી જતો નથી. તારાં કહેવા પ્રમાણે માની લઈએ કે દર્યોધન અજ્ઞાની છે. તેને જતો કરો, તો આ સંસારનું શું થાય તે તેં કદી વિચાર્યું છે? મહારાજ તો અંધ અને મમતાબદ્ધ છે. નહીં તો તેમણે ગાંધારીની વિનવણી મુજબ તેનો ત્યાગ કર્યો હોત તે ન જોઈ શકે. પણ તું નથી અંધ. નથી આસક્ત. તું કેમ નથી જોઈ શકતો કે અજ્ઞાનની ઢાલ આગળ ધરી વિચારાય તો જગતમાં કોઈનેય કશો દંડ તો શું કરાય, રોકી પણ ન શકાય. કારણ કે જે જ્ઞાની છે તે પાપ નથી કરતા, અજ્ઞાની-અણસમજુ જ દ્રોહ કરે છે. શિશુપાલ અજ્ઞાની હતો. તેને જ્ઞાન હોત તો રાજસૂય યજ્ઞ વખતે યદ્ધાંતદ્ધ બોલ્યો હોત? અજ્ઞાનના નામે અત્યાચાર થવા દઈએ તો સૃષ્ટિ ચાલે જ કઈ રીતે? જયદ્રથે કૃષ્ણાનું હરણ કર્યું; અજ્ઞાની હતો જવા દો. ભીમને ઝેર દીધું; દેનારા અજ્ઞાની હતા, જવા દો. લાક્ષાગૃહનો રચનાર અજ્ઞાની હતો, જવા દો. મારી આ મહિમાવાન ભગિનીનો કેશપાશ ખેંચનાર દુઃશાસન અજ્ઞાની હતો, જવા દો. આ સ્વીકારીએ તો શું થાય તેનો તને કંઈ ખ્યાલ છે ખરો?'
સંજય આવાક્ થઈ ગયો હતો. બધા મંત્રમુગ્ધ હતાં.
~ કુરુક્ષેત્ર પુસ્તકમાંથી, લેખક: મનુભાઈ પંચોળી 'દર્શક'
વાણી
May 05, 2026અને ધૌમ્ય ઋષિ (પાંડવોના રાજપુરોહિત) બોલ્યા ‘તેમાં ખોટું થોડું જ છે? ભગવાને વાણી આપી છે તે વેર વધારવા માટે નહિ, વેર ઘટાડવા માટે. ભીમ-દ્રૌપદીએ તે દહાડે મયસભામાં “આંધળાંનાં તો આંધળાં જ હોય'' તે વેણ ન કહ્યું હોત તો આટલી આગ ન થઈ હોત.'
સુવર્ણા (ઋષિ પત્ની) કહે, 'એ તો તમે અતિવ્યાપ્તિ કરો છો, એ નહિ તો બીજું બહાનું કાઢીનેય સુયોધને તો પાંડવોને પજવ્યા જ હોત. લાક્ષાગૃહ વખતે ક્યાં દ્રૌપદી હતાં?'
'તમારી એ વાત સાચી છે પણ તે છતાંય વાણીથી સંધાય પણ છે ને વાણીથી ભંગાય પણ છે. આજે તમે ભાંગ્યું.’
~ કુરુક્ષેત્ર પુસ્તકમાંથી, લેખક: મનુભાઈ પંચોળી 'દર્શક'
Let's Build Video Player
May 02, 2026This is the first article in the series of the articles where we are going to build video player - player. The idea is simple, we will create a minimal video player program and then extend the functionalities of it via "extension articles". Let's see how things will go! I will update the following list as I publish the article(s) in this series.
- Let's Build Video Player
tl;dc: Refer this gist to get the final version of player.c code.
You need following:
- GCC -
sudo apt install build-essential - GTK4 -
sudo apt install libgtk-4-dev - GStreamer & plugins -
sudo apt install libgstreamer1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good
Go ahead and create a file with name player.c and write the following stub code.
#include <gtk/gtk.h> static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
If you need brief explanation on this code, refer the Let's Build Terminal Pt. 1 article. Although, it is from "Let's Build Terminal" series but the first part is generic enough to understand such a code.
Use following command to compile and run the program.
gcc player.c `pkg-config --cflags --libs gtk4` && ./a.out
Let's add the header bar. The plan is to have a "Open" button in header bar that allow us to select the video file to open and play.
We can create a header bar using gtk_header_bar_new() function and then give a title to it using gtk_window_set_titlebar() function to set the header bar as title bar of the window.
#include <gtk/gtk.h> static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
Now, go ahead and create a button using gtk_button_new_with_label() function and then pack it to the header bar.
#include <gtk/gtk.h> static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
Run the program and it should produce output like this.
When user click on the button, it should open a file dialog to select the video. We need to pass the window instance as user data because it is needed to load the video into the window.
#include <gtk/gtk.h> static void _on_open_clicked(GtkWidget* button, gpointer data) { } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); g_signal_connect(button, "clicked", G_CALLBACK(_on_open_clicked), window); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
Let's cast and save the window passed as user data and create a file dialog using gtk_file_dialog_new() function.
#include <gtk/gtk.h> static void _on_open_clicked(GtkWidget* button, gpointer data) { GtkWindow* window = GTK_WINDOW(data); GtkFileDialog* file_dialog = gtk_file_dialog_new(); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); g_signal_connect(button, "clicked", G_CALLBACK(_on_open_clicked), window); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
In order to actually see the file dialog, we need to call the gtk_file_dialog_open() function. We need to pass 5 arguments - dialog itself, window as parent, NULL as cancellable operation, callback function, and user data.
#include <gtk/gtk.h> static void _on_open_clicked(GtkWidget* button, gpointer data) { GtkWindow* window = GTK_WINDOW(data); GtkFileDialog* file_dialog = gtk_file_dialog_new(); gtk_file_dialog_open(file_dialog, window, NULL, _on_file_opened, window); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); g_signal_connect(button, "clicked", G_CALLBACK(_on_open_clicked), window); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
We need to define the _on_file_opened() function. But is a asnyc callback. Due to this it accepts these parameters - source object that has started asnyc operation (file dialog) of type GObject*, result of the operation of type GAsyncResult*, and user data.
#include <gtk/gtk.h> static void _on_file_opened(GObject* source_object, GAsyncResult* res, gpointer data) { } static void _on_open_clicked(GtkWidget* button, gpointer data) { GtkWindow* window = GTK_WINDOW(data); GtkFileDialog* file_dialog = gtk_file_dialog_new(); gtk_file_dialog_open(file_dialog, window, NULL, _on_file_opened, window); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); g_signal_connect(button, "clicked", G_CALLBACK(_on_open_clicked), window); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
Again, let's get the values of dialog and window from the function parameters.
#include <gtk/gtk.h> static void _on_file_opened(GObject* source_object, GAsyncResult* res, gpointer data) { GtkFileDialog* file_dialog = GTK_FILE_DIALOG(source_object); GtkWindow* window = GTK_WINDOW(data); } static void _on_open_clicked(GtkWidget* button, gpointer data) { GtkWindow* window = GTK_WINDOW(data); GtkFileDialog* file_dialog = gtk_file_dialog_new(); gtk_file_dialog_open(file_dialog, window, NULL, _on_file_opened, window); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); g_signal_connect(button, "clicked", G_CALLBACK(_on_open_clicked), window); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
We need to call the gtk_file_dialog_open_finish() function. This function finish the gtk_file_dialog_open() function and return either the selected file or an error.
#include <gtk/gtk.h> static void _on_file_opened(GObject* source_object, GAsyncResult* res, gpointer data) { GtkFileDialog* file_dialog = GTK_FILE_DIALOG(source_object); GtkWindow* window = GTK_WINDOW(data); GFile* file = NULL; GError* error = NULL; file = gtk_file_dialog_open_finish(file_dialog, res, &error); } static void _on_open_clicked(GtkWidget* button, gpointer data) { GtkWindow* window = GTK_WINDOW(data); GtkFileDialog* file_dialog = gtk_file_dialog_new(); gtk_file_dialog_open(file_dialog, window, NULL, _on_file_opened, window); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); g_signal_connect(button, "clicked", G_CALLBACK(_on_open_clicked), window); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
If we get the error, we need to stop and free the error memory using g_error_free(). We can also print the error message using g_printerr() function.
#include <gtk/gtk.h> static void _on_file_opened(GObject* source_object, GAsyncResult* res, gpointer data) { GtkFileDialog* file_dialog = GTK_FILE_DIALOG(source_object); GtkWindow* window = GTK_WINDOW(data); GFile* file = NULL; GError* error = NULL; file = gtk_file_dialog_open_finish(file_dialog, res, &error); if (error) { g_printerr("Error opening file %s\n", error->message); g_error_free(error); return; } } static void _on_open_clicked(GtkWidget* button, gpointer data) { GtkWindow* window = GTK_WINDOW(data); GtkFileDialog* file_dialog = gtk_file_dialog_new(); gtk_file_dialog_open(file_dialog, window, NULL, _on_file_opened, window); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); g_signal_connect(button, "clicked", G_CALLBACK(_on_open_clicked), window); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
But, if we have file, we can proceed with playing the video on the window. Let's create a video widget using gtk_video_new() function and then set it as child of the window.
#include <gtk/gtk.h> static void _on_file_opened(GObject* source_object, GAsyncResult* res, gpointer data) { GtkFileDialog* file_dialog = GTK_FILE_DIALOG(source_object); GtkWindow* window = GTK_WINDOW(data); GFile* file = NULL; GError* error = NULL; file = gtk_file_dialog_open_finish(file_dialog, res, &error); if (error) { g_printerr("Error opening file %s\n", error->message); g_error_free(error); return; } if (file) { GtkWidget* video = gtk_video_new(); gtk_window_set_child(window, video); } } static void _on_open_clicked(GtkWidget* button, gpointer data) { GtkWindow* window = GTK_WINDOW(data); GtkFileDialog* file_dialog = gtk_file_dialog_new(); gtk_file_dialog_open(file_dialog, window, NULL, _on_file_opened, window); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); g_signal_connect(button, "clicked", G_CALLBACK(_on_open_clicked), window); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
Let's create a media stream from the given file using gtk_media_fil_new_from_file() and set this steam to the video using gtk_video_set_media_stream(). Don't forget to unref the file object.
#include <gtk/gtk.h> static void _on_file_opened(GObject* source_object, GAsyncResult* res, gpointer data) { GtkFileDialog* file_dialog = GTK_FILE_DIALOG(source_object); GtkWindow* window = GTK_WINDOW(data); GFile* file = NULL; GError* error = NULL; file = gtk_file_dialog_open_finish(file_dialog, res, &error); if (error) { g_printerr("Error opening file %s\n", error->message); g_error_free(error); return; } if (file) { GtkWidget* video = gtk_video_new(); GtkMediaStream* media = GTK_MEDIA_STREAM(gtk_media_file_new_for_file(file)); gtk_video_set_media_stream(GTK_VIDEO(video), media); gtk_window_set_child(window, video); g_object_unref(file); } } static void _on_open_clicked(GtkWidget* button, gpointer data) { GtkWindow* window = GTK_WINDOW(data); GtkFileDialog* file_dialog = gtk_file_dialog_new(); gtk_file_dialog_open(file_dialog, window, NULL, _on_file_opened, window); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Player"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Player")); // Button. GtkWidget* button = gtk_button_new_with_label("Open"); g_signal_connect(button, "clicked", G_CALLBACK(_on_open_clicked), window); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.player", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); return status; }
And with these changes, we now have the video player. Go ahead and run the program to confirm the video player!
Yay!
TIL: #include literally copy-paste the content of it
May 01, 2026I mean I already knew about this point already but I was still thinking that there will be some magic in-between. It can't be that simple - copy-paste! But, the I watched this video by antirez.
---
Create a file with name print.c and write the following code - yes, just a printf() statement.
printf("hello, world\n");
Create another file with name hello.c and write the following code.
#include <stdio.h> int main(void) { #include "print.c" return 0; }
Now, compile and run the hello.c program (without including print.c in compilation).
gcc hello.c && ./a.out hello, world
It prints the output - hello, world as #include directive copy-paste the content of print.c file.
If you need proof then use -E compilation option. It'll print the preprocessed output. Let's also pass -P option to pretty-print the output.
gcc -E –P hello.c
The output is big. So, I truncated to only last few lines.
// ... // ... extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); extern int __uflow (FILE *); extern int __overflow (FILE *, int); int main(void) { printf("hello, world\n"); return 0; }
There it is!
