--- clock.c	2005-04-12 16:46:46.826097032 -0600
+++ clock.c	2005-04-12 16:55:39.566108240 -0600
@@ -3,6 +3,7 @@
  *  Copyright 2002,2004 Jasper Huijsmans(jasper@xfce.org)
  *                      Olivier Fourdan (fourdan@xfce.org)
  *                      Xavier Maillard (zedek@fxgsproject.org)
+ *                      Choe Hwanjin(krisna@kldp.org)
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -59,7 +60,9 @@
 {
     GtkWidget *eventbox;
     GtkWidget *clock;		/* our XfceClock widget */
+    GtkWidget *calendar;	/* our XfceCalendar popup */
 
+	gint orientation;	/* panel orientation */
     int timeout_id;		/* update the date tooltip */
 }
 t_clock;
@@ -89,86 +92,117 @@
 }
 ClockDialog;
 
-/* start xfcalendar or send a client message
- * NOTE: keep message format in sync with xfcalendar */
-static gboolean retry_popup_xfcalendar (GtkWidget * widget);
-
-static gboolean
-popup_xfcalendar (GtkWidget * widget, guint32 time)
-{
-    GdkAtom atom;
-    Window xwindow;
-    static guint32 start_time = 0;
-
-    /* send message to xfcalendar if it is running */
-    atom = gdk_atom_intern ("_XFCE_CALENDAR_RUNNING", FALSE);
-    if ((xwindow = XGetSelectionOwner (GDK_DISPLAY (),
-				       gdk_x11_atom_to_xatom (atom))) != None)
-    {
-	char msg[20];
-	const char *fmt = "%lx:%s";
-	Window xid = GDK_WINDOW_XID (widget->window);
-	GdkEventClient gev;
-
-	/* popup in the same direction as menus */
-	switch (groups_get_arrow_direction ())
-	{
-	    case GTK_ARROW_UP:
-		sprintf (msg, fmt, xid, "up");
-		break;
-	    case GTK_ARROW_DOWN:
-		sprintf (msg, fmt, xid, "down");
-		break;
-	    case GTK_ARROW_LEFT:
-		sprintf (msg, fmt, xid, "left");
-		break;
-	    case GTK_ARROW_RIGHT:
-		sprintf (msg, fmt, xid, "right");
-		break;
-	    default:
-		return FALSE;
-	}
-
-	gev.type = GDK_CLIENT_EVENT;
-	gev.window = widget->window;
-	gev.send_event = TRUE;
-	gev.message_type =
-	    gdk_atom_intern ("_XFCE_CALENDAR_TOGGLE_HERE", FALSE);
-	gev.data_format = 8;
-	strcpy (gev.data.b, msg);
-
-	gdk_event_send_client_message ((GdkEvent *) & gev,
-				       (GdkNativeWindow) xwindow);
-	gdk_flush ();
-
-	return TRUE;
-    }
-    else if (time > start_time + 2000 || start_time == 0)
-    {
-	start_time = time;
-	exec_cmd_silent ("xfcalendar", FALSE, FALSE);
-	g_timeout_add (1000, (GSourceFunc) retry_popup_xfcalendar, widget);
+/* creation of calendar popup */
+static GtkWidget *
+pop_calendar_window(GtkWidget *parent, int orientation)
+{
+    GtkWidget *window;
+    GtkWidget *cal;
+    gint parent_x, parent_y, parent_w, parent_h;
+    gint root_w, root_h;
+    gint width, height, x, y;
+    guint day;
+    GtkRequisition requisition;
+    GtkAllocation allocation;
+
+    window = gtk_window_new(GTK_WINDOW_POPUP);
+
+    cal = gtk_calendar_new();
+
+    gtk_calendar_get_date(GTK_CALENDAR(cal), NULL, NULL, &day);
+    gtk_calendar_mark_day(GTK_CALENDAR(cal), day);
+    gtk_container_add(GTK_CONTAINER(window), cal);
+
+    gdk_window_get_origin(GDK_WINDOW(parent->window), &parent_x, &parent_y);
+    gdk_drawable_get_size(GDK_DRAWABLE(parent->window), &parent_w, &parent_h);
+
+    root_w = gdk_screen_width();
+    root_h = gdk_screen_height();
+
+    gtk_widget_realize(GTK_WIDGET(window));
+
+    gtk_widget_size_request(GTK_WIDGET(cal), &requisition);
+
+    allocation.x = requisition.width;
+    allocation.y = requisition.height;
+    gtk_widget_size_allocate(GTK_WIDGET(cal), &allocation);
+
+    gtk_widget_size_request(GTK_WIDGET(cal), &requisition);
+    width = requisition.width;
+    height = requisition.height;
+
+    if (orientation == GTK_ORIENTATION_VERTICAL) {
+        if (parent_x < root_w / 2) {
+            if (parent_y < root_h / 2) {
+                /* upper left */
+                x = parent_x + parent_w;
+                y = parent_y;
+            } else {
+                /* lower left */
+                x = parent_x + parent_w;
+                y = parent_y + parent_h - height;
+            }
+        } else {
+            if (parent_y < root_h / 2) {
+                /* upper right */
+                x = parent_x - parent_w;
+                y = parent_y;
+            } else {
+                /* lower right */
+                x = parent_x - parent_w;
+                y = parent_y + parent_h - height;
+            }
+        }
+    } else {
+        if (parent_x < root_w / 2) {
+            if (parent_y < root_h / 2) {
+                /* upper left */
+                x = parent_x;
+                y = parent_y + parent_h;
+            } else {
+                /* lower left */
+                x = parent_x;
+                y = parent_y - height;
+            }
+        } else {
+            if (parent_y < root_h / 2) {
+                /* upper right */
+                x = parent_x + parent_w - width;
+                y = parent_y + parent_h;
+            } else {
+                /* lower right */
+                x = parent_x + parent_w - width;
+                y = parent_y - height;
+            }
+        }
     }
 
-    return FALSE;
-}
+    gtk_window_move(GTK_WINDOW(window), x, y);
+    gtk_widget_show(cal);
+    gtk_widget_show(window);
 
-static gboolean
-retry_popup_xfcalendar (GtkWidget * widget)
-{
-    popup_xfcalendar (widget, gtk_get_current_event_time ());
-    return FALSE;
+    return window;
 }
 
 static gboolean
 on_button_press_event_cb (GtkWidget * widget,
-			  GdkEventButton * event, Control * control)
+			  GdkEventButton * event, gpointer data)
 {
     if (event->button == 1)
     {
-	return popup_xfcalendar (control->base, event->time);
-    }
+        t_clock *clock;
 
+        if (data == NULL) return FALSE;
+
+        clock = (t_clock *)data;
+        if (clock->calendar != NULL) {
+            gtk_widget_destroy(clock->calendar);
+            clock->calendar = NULL;
+        } else {
+            clock->calendar = pop_calendar_window(clock->eventbox, clock->orientation);
+        }
+        return TRUE;
+    }
     return FALSE;
 }
 
@@ -242,6 +276,8 @@
 		       clock->eventbox);
 
     /* callback for calendar popup */
+    clock->calendar = NULL;
+    clock->orientation = GTK_ORIENTATION_HORIZONTAL;
     g_signal_connect (G_OBJECT (clock->eventbox), "button-press-event",
 		      G_CALLBACK (on_button_press_event_cb), clock);
 
@@ -310,6 +346,13 @@
     update_clock_size (tmp, size);
 }
 
+void
+clock_set_orientation(Control *control, int orientation)
+{
+    t_clock *clock = control->data;
+    clock->orientation = orientation;
+}
+
 /* Write the configuration at exit */
 void
 clock_write_config (Control * control, xmlNodePtr parent)
@@ -691,6 +734,7 @@
     cc->create_options = clock_create_options;
 
     cc->set_size = clock_set_size;
+    cc->set_orientation = clock_set_orientation;
 
     control_class_set_unique (cc, TRUE);
 }

