Path: blob/master/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c
41153 views
/*1* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#ifdef HEADLESS26#error This file should not be included in headless library27#endif2829#include <dlfcn.h>30#include "jvm_md.h"31#include <setjmp.h>32#include <string.h>3334#include "jni_util.h"35#include "awt_Taskbar.h"363738extern JavaVM *jvm;3940#define NO_SYMBOL_EXCEPTION 14142#define UNITY_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("unity", "9")43#define UNITY_LIB JNI_LIB_NAME("unity")4445static jmp_buf j;4647static void *unity_libhandle = NULL;4849static DbusmenuMenuitem* menu = NULL;50UnityLauncherEntry* entry = NULL;5152static jclass jTaskbarCls = NULL;53static jmethodID jTaskbarCallback = NULL;54static jmethodID jMenuItemGetLabel = NULL;5556GList* globalRefs = NULL;5758static void* dl_symbol(const char* name) {59void* result = dlsym(unity_libhandle, name);60if (!result)61longjmp(j, NO_SYMBOL_EXCEPTION);6263return result;64}6566static gboolean unity_load() {67unity_libhandle = dlopen(UNITY_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);68if (unity_libhandle == NULL) {69unity_libhandle = dlopen(UNITY_LIB, RTLD_LAZY | RTLD_LOCAL);70if (unity_libhandle == NULL) {71return FALSE;72}73}74if (setjmp(j) == 0) {75fp_unity_launcher_entry_get_for_desktop_file = dl_symbol("unity_launcher_entry_get_for_desktop_file");76fp_unity_launcher_entry_set_count = dl_symbol("unity_launcher_entry_set_count");77fp_unity_launcher_entry_set_count_visible = dl_symbol("unity_launcher_entry_set_count_visible");78fp_unity_launcher_entry_set_urgent = dl_symbol("unity_launcher_entry_set_urgent");79fp_unity_launcher_entry_set_progress = dl_symbol("unity_launcher_entry_set_progress");80fp_unity_launcher_entry_set_progress_visible = dl_symbol("unity_launcher_entry_set_progress_visible");8182fp_dbusmenu_menuitem_new = dl_symbol("dbusmenu_menuitem_new");83fp_dbusmenu_menuitem_property_set = dl_symbol("dbusmenu_menuitem_property_set");84fp_dbusmenu_menuitem_property_set_int = dl_symbol("dbusmenu_menuitem_property_set_int");85fp_dbusmenu_menuitem_property_get_int = dl_symbol("dbusmenu_menuitem_property_get_int");86fp_dbusmenu_menuitem_property_set = dl_symbol("dbusmenu_menuitem_property_set");87fp_dbusmenu_menuitem_child_append = dl_symbol("dbusmenu_menuitem_child_append");88fp_dbusmenu_menuitem_child_delete = dl_symbol("dbusmenu_menuitem_child_delete");89fp_dbusmenu_menuitem_take_children = dl_symbol("dbusmenu_menuitem_take_children");90fp_dbusmenu_menuitem_foreach = dl_symbol("dbusmenu_menuitem_foreach");91fp_unity_launcher_entry_set_quicklist = dl_symbol("unity_launcher_entry_set_quicklist");92fp_unity_launcher_entry_get_quicklist = dl_symbol("unity_launcher_entry_get_quicklist");93} else {94dlclose(unity_libhandle);95unity_libhandle = NULL;96return FALSE;97}98return TRUE;99}100101void callback(DbusmenuMenuitem* mi, guint ts, jobject data) {102JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);103(*env)->CallStaticVoidMethod(env, jTaskbarCls, jTaskbarCallback, data);104}105106/*107* Class: sun_awt_X11_XTaskbarPeer108* Method: init109* Signature: (Ljava/lang/String;)Z110*/111JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XTaskbarPeer_init112(JNIEnv *env, jclass cls, jstring jname, jint version, jboolean verbose) {113jclass clazz;114115jTaskbarCls = (*env)->NewGlobalRef(env, cls);116117CHECK_NULL_RETURN(jTaskbarCallback =118(*env)->GetStaticMethodID(env, cls, "menuItemCallback", "(Ljava/awt/MenuItem;)V"), JNI_FALSE);119CHECK_NULL_RETURN(120clazz = (*env)->FindClass(env, "java/awt/MenuItem"), JNI_FALSE);121CHECK_NULL_RETURN(122jMenuItemGetLabel = (*env)->GetMethodID(env, clazz, "getLabel", "()Ljava/lang/String;"), JNI_FALSE);123124if (gtk_load(env, version, verbose) && unity_load()) {125const gchar* name = (*env)->GetStringUTFChars(env, jname, NULL);126if (name) {127entry = fp_unity_launcher_entry_get_for_desktop_file(name);128(*env)->ReleaseStringUTFChars(env, jname, name);129return JNI_TRUE;130}131}132return JNI_FALSE;133}134135/*136* Class: sun_awt_X11_XTaskbarPeer137* Method: runloop138* Signature: ()V139*/140JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_runloop141(JNIEnv *env, jclass cls) {142gtk->gdk_threads_enter();143gtk->gtk_main();144gtk->gdk_threads_leave();145}146147/*148* Class: sun_awt_X11_XTaskbarPeer149* Method: setBadge150* Signature: (JZ)V151*/152JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setBadge153(JNIEnv *env, jobject obj, jlong value, jboolean visible) {154gtk->gdk_threads_enter();155fp_unity_launcher_entry_set_count(entry, value);156fp_unity_launcher_entry_set_count_visible(entry, visible);157DbusmenuMenuitem* m;158if (m = fp_unity_launcher_entry_get_quicklist(entry)) {159fp_unity_launcher_entry_set_quicklist(entry, m);160}161gtk->gdk_threads_leave();162}163164/*165* Class: sun_awt_X11_XTaskbarPeer166* Method: setUrgent167* Signature: (Z)V168*/169JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setUrgent170(JNIEnv *env, jobject obj, jboolean urgent) {171gtk->gdk_threads_enter();172fp_unity_launcher_entry_set_urgent(entry, urgent);173DbusmenuMenuitem* m;174if (m = fp_unity_launcher_entry_get_quicklist(entry)) {175fp_unity_launcher_entry_set_quicklist(entry, m);176}177gtk->gdk_threads_leave();178}179180/*181* Class: sun_awt_X11_XTaskbarPeer182* Method: updateProgress183* Signature: (DZ)V184*/185JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_updateProgress186(JNIEnv *env, jobject obj, jdouble value, jboolean visible) {187gtk->gdk_threads_enter();188fp_unity_launcher_entry_set_progress(entry, value);189fp_unity_launcher_entry_set_progress_visible(entry, visible);190DbusmenuMenuitem* m;191if (m = fp_unity_launcher_entry_get_quicklist(entry)) {192fp_unity_launcher_entry_set_quicklist(entry, m);193}194gtk->gdk_threads_leave();195}196197void deleteGlobalRef(gpointer data) {198JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);199(*env)->DeleteGlobalRef(env, data);200}201202void fill_menu(JNIEnv *env, jobjectArray items) {203int index;204jsize length = (*env)->GetArrayLength(env, items);205for (index = 0; index < length; index++) {206jobject elem = (*env)->GetObjectArrayElement(env, items, index);207if ((*env)->ExceptionCheck(env)) {208break;209}210elem = (*env)->NewGlobalRef(env, elem);211212globalRefs = gtk->g_list_append(globalRefs, elem);213214jstring jlabel = (jstring) (*env)->CallObjectMethod(env, elem, jMenuItemGetLabel);215if (!(*env)->ExceptionCheck(env) && jlabel) {216const gchar* label = (*env)->GetStringUTFChars(env, jlabel, NULL);217if (label) {218DbusmenuMenuitem* mi = fp_dbusmenu_menuitem_new();219if (!strcmp(label, "-")) {220fp_dbusmenu_menuitem_property_set(mi, "type", "separator");221} else {222fp_dbusmenu_menuitem_property_set(mi, "label", label);223}224225(*env)->ReleaseStringUTFChars(env, jlabel, label);226fp_dbusmenu_menuitem_child_append(menu, mi);227gtk->g_signal_connect_data(mi, "item_activated",228G_CALLBACK(callback), elem, NULL, 0);229}230}231}232}233234/*235* Class: sun_awt_X11_XTaskbarPeer236* Method: setNativeMenu237* Signature: ([Ljava/awt/MenuItem;)V238*/239JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setNativeMenu240(JNIEnv *env, jobject obj, jobjectArray items) {241242gtk->gdk_threads_enter();243244if (!menu) {245menu = fp_dbusmenu_menuitem_new();246fp_unity_launcher_entry_set_quicklist(entry, menu);247}248249GList* list = fp_dbusmenu_menuitem_take_children(menu);250gtk->g_list_free_full(list, gtk->g_object_unref);251252gtk->g_list_free_full(globalRefs, deleteGlobalRef);253globalRefs = NULL;254255if (items) {256fill_menu(env, items);257}258259gtk->gdk_threads_leave();260}261262263