diff --git a/c/gtk3/alarm-clock/alarmclock.c b/c/gtk3/alarm-clock/alarmclock.c new file mode 100644 index 0000000..063696d --- /dev/null +++ b/c/gtk3/alarm-clock/alarmclock.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include + + +const double pi = 3.141592653589793; + +GtkWidget *hours[3], *minutes[3]; +GtkWidget *enable_alarm; + + +// This function plays beep via OpenAL. +// It's may be difficult to understand how it works, so just use it as is. +// This function uses OpenAL, so you need +// to include and +// and link with OpenAL library (for GCC add param: -lopenal) +void beep() { + const int frequency = 440; + const int rate = 10000; + + ALCshort samples[2000]; + const int count = 2000; + + for(int i = 0; i < count; ++i) + samples[i] = (int)(32760*sin(2*pi*i*frequency/rate)); + + ALCdevice *device = alcOpenDevice(NULL); + ALCcontext *context = alcCreateContext(device, NULL); + alcMakeContextCurrent(context); + + ALuint buffer, source; + alGenBuffers(1, &buffer); + alBufferData(buffer, AL_FORMAT_MONO16, samples, sizeof(samples), rate); + alGenSources(1, &source); + alSourcei(source, AL_BUFFER, buffer); + alSourcePlay(source); + + g_usleep(count*1000000/rate + 10000); + + alcMakeContextCurrent(NULL); + alcDestroyContext(context); + alcCloseDevice(device); +} + +gboolean timeout(gpointer data) { + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enable_alarm))) { + time_t timer = time(NULL); + struct tm *t = localtime(&timer); + for(int i = 0; i < 3; ++i) { + int hour = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(hours[i])); + int minute = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(minutes[i])); + if (hour == t->tm_hour && minute == t->tm_min) + beep(); + } + } + return TRUE; +} + +void activate(GtkApplication* app, gpointer data) { + GtkWidget *window = gtk_application_window_new (app); + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); + gtk_container_add(GTK_CONTAINER(window), vbox); + + GtkWidget *label = gtk_label_new("Set following three alarm clocks,\nenable alarm\nand take a sleep."); + gtk_container_add(GTK_CONTAINER(vbox), label); + + for(int i = 0; i < 3; ++i) { + GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + + hours[i] = gtk_spin_button_new(NULL, 1.2, 0); + gtk_spin_button_set_range(GTK_SPIN_BUTTON(hours[i]), 0.0, 23.0); + gtk_spin_button_set_increments(GTK_SPIN_BUTTON(hours[i]), 1.0, 10.0); + gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(hours[i]), TRUE); + gtk_container_add(GTK_CONTAINER(hbox), hours[i]); + + minutes[i] = gtk_spin_button_new(NULL, 1.2, 0); + gtk_spin_button_set_range(GTK_SPIN_BUTTON(minutes[i]), 0.0, 59.0); + gtk_spin_button_set_increments(GTK_SPIN_BUTTON(minutes[i]), 1.0, 10.0); + gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(minutes[i]), TRUE); + gtk_container_add(GTK_CONTAINER(hbox), minutes[i]); + } + + // set initial values + time_t timer = time(NULL); + struct tm *t = localtime(&timer); + int h = t->tm_hour; + int m = t->tm_min; + + gtk_spin_button_set_value(GTK_SPIN_BUTTON(hours[0]), h); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(minutes[0]), m); + + m += 1; + if (m >= 60) { m -= 60; h = (h + 1)%24; } + gtk_spin_button_set_value(GTK_SPIN_BUTTON(hours[1]), h); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(minutes[1]), m); + + m += 4; + if (m >= 60) { m -= 60; h = (h + 1)%24; } + gtk_spin_button_set_value(GTK_SPIN_BUTTON(hours[2]), h); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(minutes[2]), m); + + enable_alarm = gtk_check_button_new_with_label("Enable alarm"); + gtk_container_add(GTK_CONTAINER(vbox), enable_alarm); + + gtk_widget_show_all(window); + + g_timeout_add(1000, timeout, NULL); +} + +int main(int argc, char **argv) { + GtkApplication *application = gtk_application_new(NULL, 0); + g_signal_connect(application, "activate", G_CALLBACK(activate), NULL); + int status = g_application_run(G_APPLICATION(application), argc, argv); + g_object_unref(application); + return status; +} + + diff --git a/c/gtk3/alarm-clock/readme b/c/gtk3/alarm-clock/readme new file mode 100644 index 0000000..89f4233 --- /dev/null +++ b/c/gtk3/alarm-clock/readme @@ -0,0 +1,3 @@ +this example requires OpenAL to play beeps, +so GCC commandline to compile it becomes: + gcc -lm `pkg-config --cflags --libs gtk+-3.0 openal` *.c