| 一些小型的應用程式很少使用處理序間通訊機制,但在Linux系統中,可利用D-Bus擷取作業系統的變化。例如在案頭環境退出時,D-Bus將發出相關訊號告知接入系統匯流排的程式,使這些程式能夠在強制退出前儲存資料。除此以外,音量大小、網路連接、新的檔案系統被掛載(CDROM、USB磁碟機)都可由D-Bus報告。這是因為Linux的多種案頭環境均使用D-Bus,應用程式的可移植性也得到了保證。本節將介紹媒體播放器使用D-Bus的執行個體。 16.3.1 媒體播放器在案頭環境退出時響應 媒體播放器需要使用圖形介面,而圖形介面必須依賴於一種Linux案頭環境。Linux的核心與案頭環境是分離的,在系統退出前首先會結束案頭會話,因此可通過D-Bus獲得案頭環境退出的訊息。媒體播放器退出前需要進行一系統工作,例如儲存當前程式介面的資料、儲存播放清單等,這些工作在核心控制模組收到GENERAL_EXIT指令後進行。使用D-Bus需啟動GLib主迴圈,相關代碼可放在主函數或某個獨立的函數內,代碼如下: #include <glib.h> // 包含glib庫 #include <dbus/dbus-glib.h> // 包含glib庫中D-Bus管理庫 int link_dbus() { GMainLoop *loop; // 定一個事件迴圈對象的指標 DBusConnection *bus; // 定義匯流排連線物件的指標 DBusError error; // 定義D-Bus錯誤訊息對象 loop = g_main_loop_new(NULL, FALSE); // 建立新事件迴圈對象 dbus_error_init(&error); // 將錯誤訊息對象串連到D-Bus錯誤訊息對象 bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error); // 串連到系統匯流排 if (!bus) { // 判斷是否串連錯誤 g_warning("串連到D-Bus失敗: %s", error.message); // 使用GLib輸出錯誤警告資訊 dbus_error_free(&error); // 清除錯誤訊息 return 1; } dbus_connection_setup_with_g_main(bus, NULL);// 將匯流排設為接收GLib事件 // 迴圈 dbus_bus_add_match(bus, "type='signal',interface='com.system.dbus.Signal'"); // 定義匹配器 dbus_connection_add_filter(bus, general_exit, loop, NULL); // 調用函數接收訊息 g_main_loop_run(loop); // 啟動事件迴圈 return 0; } 該函數串連到D-Bus的系統匯流排中,並接收com.system.dbus.Signal管道內的資訊,系統關閉資訊即通過該管道傳送。當接收到任何訊息後,將調用general_exit()函數進行處理,代碼如下: static DBusHandlerResult // 定義接收訊息函數的細節 general_exit (DBusConnection *connection, DBusMessage *message, void*user_data) { GMainLoop *loop = user_data; // 定義事件迴圈對象的指標,並與主函數中 // 的同步 if (dbus_message_is_signal // 接收串連成功訊息,判斷是否串連失敗 (message, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, "Disconnected")) { g_main_loop_quit (loop); // 退出主迴圈 return DBUS_HANDLER_RESULT_HANDLED; } if (dbus_message_is_signal(message, "com.burtonini.dbus.Signal", "Ping")) { // 指定訊息物件路徑,判斷是否成功 DBusError error; // 定義錯誤對象 char *s; dbus_error_init(&error); // 將錯誤訊息對象串連到D-Bus錯誤訊息 // 對象 if (dbus_message_get_args // 接收訊息,並判斷是否有錯誤 (message, &error, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) { if (!strcmp(s, "SHUTDOWN")) { // 判斷收到的訊息是否為系統關閉資訊 main_core(GENERAL_EXIT, NULL); // 調用核心控制模組 dbus_free (s); // 清除該訊息 } } else { // 有錯誤時執行下列語句 g_print("訊息已收到,但有錯誤提示: %s\n", error.message); dbus_error_free (&error); } return DBUS_HANDLER_RESULT_HANDLED; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } 該函數將在收到系統資訊時運行,首先判斷收到的資訊是否為系統關閉資訊,如果是,則調用核心控制模組進行處理。 16.3.2 調整系統音量 Linux系統使用通用的音頻介面OSS(Open Sound System)管理音效卡,該介面建立在音效卡驅動程式之上,可操作任何類型的音效卡。選擇“系統”|“喜好設定”|“硬體”|“音效”命令,可開啟相關配置視窗,如圖16.1所示。 調整系統音量可通過調用OSS實現,在C語言程式中使用該介面首選需要安裝相關函數庫。下載原始碼可訪問其官方網站,地址為http://www.opensound.com。或者在終端中輸入下列命令: yum install oss-devel 安裝後,標頭檔的路徑位於“/usr/include/oss”目錄中,編譯使用OSS的程式需要加入編譯指令“`pkg-config --cflags --libs oss`”。 圖16.1 查看音效卡 1.調節音量 媒體播放器調節音量的操作是向核心控制模組發送GENERAL_VOLUME指令,核心控制模組調用general_volume()函數進行操作。首先在main_core.c檔案中加入下列標頭檔: #include <ioctl.h> // 提供I/O操作相關控制函數 #include <unistd.h> // 標準函數庫 #include <fcntl.h> // 提供檔案操作相關控制函數 #include <sys/soundcard.h> // 提供音效卡配置相關係統調用 #include <oss.h> // OSS函數庫 然後實現general_volume()函數細節,代碼如下: int general_volume(*((int*) data)) // 設定音量 { int mixer_fd; // 用於調音器標識符 mixer_fd = oss_get_mixer(); // 獲得調音器的標識符 if (*data < 0 || *data > 100) { // 判斷輸入的數值是否有誤 printf("輸入的音量大小值有誤\n"); return 0; } if (ioctl(mixer_fd, SOUND_MIXER_WRITE(SOUND_MIXER_WAV), data) == -1) { // 開啟音效卡裝置檔案,設定音量 printf("無法開啟指定音效卡\n"); return 0; } return 1; } |