Tampilkan postingan dengan label GDK. Tampilkan semua postingan
Tampilkan postingan dengan label GDK. Tampilkan semua postingan

Sabtu, 16 Januari 2016

Membuat Program Screenshot dengan C



Untuk dapat mengambil screenshot, program harus berkomunikasi dengan system atau display manager melalui API. Di Linux, hal ini dimungkinkan dengan library display manager yang disediakan oleh X. Namun cara ini kurang portabel, jadi sebagai alternatif kita bisa menggunakan library crossplatform GDK. Jika anda sudah pernah membuat program GTK, maka ini tidak akan sulit, karena GDK sendiri sangat erat hubungannya dengan GTK. Namun Jika belum, silahkan membaca tutorial Hello World GTK dahulu untuk menyiapkan library yang diperlukan.

Untuk dapat memahami bagaimana screenshot yang didemonstrasikan disini bekerja, anda harus mengetahui beberapa istilah baru yang digunakan dalam GDK dan X11:
  • Screen : yaitu layar penampil dimana seluruh window dan pointer mouse berada.
  • Window : Dalam sistem Linux Window dimanajemen secara hierarki, seperti halnya filesystem. Window yang menjadi pangkal dan merupakan parent dari window lain disebut sebagai root window. Semua region segiempat di desktop linux sebenarnya merupakan kumpulan dari window yang diatur tampilannya sedemikian rupa. Baik button, textbox, menu, semua itu merupakan window.
  • Pixbuf : Merupakan singkatan dari pixel buffer. Pixbuf bertugas menyimpan data gambar dalam memori. Data inilah yang bisa diambil dan diproses lebih lanjut.

Proes pengambilan screenshot yang ditunjukkan disini sangat sederhana. Pertama kita mencari tahu screen default yang sedang ditampilkan di monitor.

GdkScreen * gdk_screen_get_default (void);

Kemudian dilanjutkan dengan mengambil root window dari screen. Argumen untuk parameter screen diperoleh dari pemanggilan fungsi sebelumnya.

GdkWindow * gdk_screen_get_root_window (GdkScreen *screen);

Sebelum memperoleh pixbuf, kita harus mengetahui panjang(width) dan lebar(height) dari root window.

int gdk_window_get_width (GdkWindow *window);
int gdk_window_get_height (GdkWindow *window);

Semua window menyimpan tampilan gambarnya dalam pixbuf, jadi yang harus dilakukan sekarang adalah mengambil pixbuf dari root window tersebut.

GdkPixbuf * gdk_pixbuf_get_from_window (GdkWindow *window, gint src_x, gint src_y, gint width, gint height);

src_x dan src_y adalah parameter yang menentukan titik koordinat window yang akan diambil data pixbuf-nya. Sementara itu, width dan height adalah panjang dan lebar gambar yang diambil dari window, dihitung dari src_x dan src_y.

Terakhir, kita simpan data pixbuf tersebut ke dalam file sebagai gambar JPEG.

gboolean gdk_pixbuf_save (GdkPixbuf *pixbuf, const char *filename, const char *type, GError **error, ...);

Semua parameter prototype fungsi di atas agaknya cukup jelas, hanya ada beberapa yang masih harus dijelaskan. Parameter type menentukan format gambar yang akan disimpan; kita bisa memilih “BMP”, “PNG”, “JPEG”, “ICO”, atau yang lainnya. Parameter error digunakan untuk menunjukkan pesan error jika terjadi kesalahan, parameter ini bersifat opsional. Setiap type gambar memiliki karakteristik tersendiri. Untuk mengatur karakteristik ini, kita boleh menambahkan beberapa parameter opsional, seperti tingkat kualitas atau level kompresi gambar. Setelah itu semua, argumen 0 harus dikirim sebagai parameter paling terakhir.

Sebelum itu semua dilakukan, kita harus memanggil gtk_init() terebih dahulu. Fungsi ini akan menginisialisasikan library GDK, GTK dan beserta library dependensinya.

screenshot.c



#include <gtk/gtk.h>

int main(int argc, char *argv[]){
 GdkScreen *screen;
 GdkWindow *rootWindow;
 GdkPixbuf *rootWinPixbuf;
 int screenWidth, screenHeight; 
 
  gtk_init(&argc,&argv);
 screen = gdk_screen_get_default ();
 rootWindow = gdk_screen_get_root_window(screen);
 screenWidth = gdk_window_get_width(rootWindow);
 screenHeight = gdk_window_get_height(rootWindow);
 rootWinPixbuf = gdk_pixbuf_get_from_window(rootWindow,0,0,screenWidth, screenHeight);
 gdk_pixbuf_save(rootWinPixbuf,"/home/it/screenshot.jpg","jpeg",0,NULL);
 return 0;
}


Build dengan perintah berikut.
gcc screenshot.c `pkg-config --cflags --libs gtk+-3.0`

Selamat mencoba :)
Read more

Selasa, 17 Maret 2015

GTK Programming : Membuat Idle dan Timeout


Sampai sekarang, banyak kontributor yang mengupayakan GTK menjadi thread-safe, namun hal itu rupanya sangat sulit. Untuk mengakses widget dengan fungsi GTK secara bersamaan dari thread, banyak yang merekomendasikan untuk menggunakan idle atau time out. Setelah memahami 2 konsep ini, Anda dapat mengombinasikannya dengan thread tanpa harus kawatir masalah keamanan dalam multithreading.  Jadi, apa itu idle dan timeout?
 
Idle

Idle adalah suatu fungsi yang disisipkan pada main thread. Biasanya idle digunakan untuk mengakses widget secara terus menerus saat program berjalan.
Seperti yang telah kita ketahui sebelumnya, gtk_main() sebenarnya bekerja menerima event dan melanjutkannya kepada callback yang sesuai. Dengan menambahkan sebuah idle, fungsi yang kita inginkan akan dieksekusi setelah gtk_main() menangani handle.


Untuk menambahkan idle, kita dapat memilih satu dari 2 macam metode, yaitu dengan metode dari GDK atau dengan metode dari GLib. Menurut beberapa sumber, metode dari GDK lebih aman, namun ada pula sumber yang mengatakan keduanya sama saja. Jika dilihat dari dokumentasi GTK, penggunaan metode dari GLib ataupun GDK sama sekali tidak dipermasalahkan, namun programmer dianjukan untuk memakai fungsi dari GDK.

GDK:

guint gdk_threads_add_idle (GSourceFunc function, gpointer data);

GLib:
guint g_idle_add (GSourceFunc function, gpointer data);

function : Argumen ini berupa alamat ke fungsi callback GSourceFunc yang ingin didaftarkan. GSourceFunc merupakan fungsi khusus untuk membuat idle dan timeout. Bentuk fungsinya seperti berikut:

gboolean nama_callback (gpointer user_data);
{
   //do something
}

Fungsi callback ini akan terus dipanggil selama kita masih mengembalikan TRUE. Saat fungsi selesai dengan return FALSE, maka secara otomatis idle dihapus.  

data : Argumen kedua ini berupa pointer ke data yang dikirimkan pada fungsi callback. Sifatnya opsional, jadi bisa dikosongi.
 
Timeout

Timeout kurang lebih sama dengan idle. Perbedaanya, sebelum menjalankan fungsi callback, interval akan diperiksa terlebih dahulu.


Metode untuk membuat timeout juga disediakan oleh GDK dan GLib, sama halnya dengan idle. Parameter function dan data memiliki ketentuan pemakaian yang sama dengan fungsi yang dijelaskan sebelumnya. Fungsi berikut memiliki parameter interval, yaitu jangka waktu yang dipakai sebagai patokan sebelum pemanggilan fungsi callback. Satuan interval ditulis dalam milidetik, jadi, jika ingin callback dipanggil setiap 1 detik, gunakan argumen 1000 pada parameter interval.

GDK:

guint gdk_threads_add_timeout (guint interval, GSourceFunc function, gpointer data);

GLib:
guint g_timeout_add (guint interval, GSourceFunc function, gpointer data);



Contoh Kode
#include<stdio.h>
#include<gtk/gtk.h>

GtkWidget *window;
int num = 0;
char str[20];

gboolean timeout (gpointer user_data)
{
   sprintf((char*)&str,"Timeout: %d x", num);
   gtk_window_set_title(GTK_WINDOW(window),(char*)&str);
   num++;
   return TRUE;
}

void window_destroy (GtkWidget *object, gpointer user_data)
{
    g_print("Event destroy diterima :) \n");
    gtk_main_quit();
}

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    //window baru
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"GtkWindow");
    //hubungkan signal destroy
    g_signal_connect (window, "destroy", G_CALLBACK (window_destroy),NULL);
    //daftar timeout. Fungsi akan dipanggil setiap 1000 ms (1 detik)
    gdk_threads_add_timeout(1000,timeout,0);
    //tampilkan widget
    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}

Kode di atas akan membuat timeout dengan interval 1000 ms. Fungsi timeout() didaftarkan sebagai callback. Sehingga setiap satu detik, fungsi tersebut dipanggil. Dalam fungsi tersebut kita mengubah titlebar window dengan jumlah total pemanggilan fungsi callback.

Hasil

Read more