emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* How to get notifications about system lock/unlock on Windows machine?
@ 2009-08-20 10:04 Yuva
  0 siblings, 0 replies; only message in thread
From: Yuva @ 2009-08-20 10:04 UTC (permalink / raw)
  To: Org Mode

[-- Attachment #1: Type: text/plain, Size: 2110 bytes --]

hi,
 i've implemented a simple idea, but thought it could be done in a better
way. Need your feedback.
 At work, i am running emacs+org-mode on windoze-xp computer, and i am happy
with my setup. Whenever i am away from my computer, or i am off for the day,
i generally lock my workstation and just leave (I dont shut my system down).
The org-mode clock runs even when i am not doing anything. I want it to
switch it to default task when i am away. So, i developed a simple
application which makes use of 'emacsclientw' and sends messages to
emacs-server to notify the status of my workstation.

 Briefly, my setup is like this :

in my "orged.el"

-------------------------8<---------------------8<--------------------------

;;-------------------------------------------------------------------------
;; for listening to windows-session events.
;;-------------------------------------------------------------------------


;; sets default task.
;; @todo make it more intutive
(require 'org-clock)
(set-marker org-clock-default-task
           34 (find-file "~/orged/personal/personal.org"))


;; Custom org-win-lock and org-win-unlock functions.
(defun org-win-lock()
 "runs org-preferences when workstation gets locked
Switches to default task."
 (interactive)
 (find-file (buffer-file-name (marker-buffer org-clock-default-task)))
 (goto-char org-clock-default-task)
 (org-clock-in))

(defun org-win-unlock()
 "runs org-preferences when workstation gets un-locked
Switches to interrupted task."
 (interactive)
 (find-file (buffer-file-name (marker-buffer org-clock-interrupted-task)))
 (goto-char org-clock-default-task)
 (org-clock-in))

;; start the server and notification application.
(server-start)
(start-process
 "eval-a-exe" "buf-eval-a-exe" "~/sandbox/windows-lock-notif/a.exe")

-------------------------8<---------------------8<--------------------------


 i also wrote a small application which polls on session events and send
messages to this emacs-server (see attachment).


My question is : Can it be done better?



-- 
YUVA

[-- Attachment #2: main.c --]
[-- Type: application/octet-stream, Size: 4732 bytes --]

//-------------------------------------------------------------------------
// sending async messages to emacs-server.
// for me, "server" sounds like some kind of geek term, but infact all
// i have to do is add (server-start) to my orged.el file.
//
// build it like : gcc main.c -lwtsapi32
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
// msconfig.h stuff
//-------------------------------------------------------------------------


// contains stdafx.h and other definitions.
#define WINVER   0x0501
#define WIN32_LEAN_AND_MEAN

// includes.
#include <windows.h>
#include <wtsapi32.h>


//-------------------------------------------------------------------------
// main program.
//-------------------------------------------------------------------------


// synchronizing event.
static HANDLE  hEvent;

static LRESULT OnWtsSessionChange(HWND hWnd, WPARAM wEventType)
{
   TCHAR szCmdlineOnLock[] = 
      TEXT("C:\\cygwin\\usr\\local\\nt-emacs\\bin\\emacsclientw -e \"(org-win-lock)\"");
   TCHAR szCmdlineOnUnlock[] = 
      TEXT("C:\\cygwin\\usr\\local\\nt-emacs\\bin\\emacsclientw -e \"(org-win-unlock)\"");

   PROCESS_INFORMATION piProcInfo; 
   STARTUPINFO siStartInfo;
 
   ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
   ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
   siStartInfo.cb = sizeof(STARTUPINFO); 
   siStartInfo.hStdError = NULL;
   siStartInfo.hStdOutput = NULL;
   siStartInfo.hStdInput = NULL;
   siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

   TCHAR* cmdLine = NULL;
 
   switch (wEventType)
   {
   case WTS_SESSION_LOCK :
      cmdLine = szCmdlineOnLock;
      break;

   case WTS_SESSION_UNLOCK :
      cmdLine = szCmdlineOnUnlock;
      break;

   case WTS_SESSION_LOGOFF :
      SetEvent(hEvent);
      DestroyWindow(hWnd);
      break;
   }

   CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL,
                 &siStartInfo, &piProcInfo);

   return 0;
}


static LRESULT CALLBACK 
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   LRESULT result = 0;
   switch (message)
   {
   case WM_WTSSESSION_CHANGE :
      result = OnWtsSessionChange(hWnd, wParam);
      break;

   case WM_DESTROY :
      PostQuitMessage (1);
      break;
   }

   result = DefWindowProc(hWnd, message, wParam, lParam);
   return result;
}


static DWORD WINAPI fnWaitForWtsNotifs(LPVOID lpParam)
{
   WNDCLASS wc;
   HWND hWnd;
   MSG msg;
   HANDLE hInstance = GetModuleHandle(NULL);

   wc.style = 0;                                   // Class style
   wc.lpfnWndProc = (WNDPROC) WndProc;             // Window procedure
   wc.cbClsExtra = 0;                              // Class extra bytes
   wc.cbWndExtra = 0;                              // Window extra bytes
   wc.hInstance = (HINSTANCE)hInstance;            // Instance handle
   wc.hIcon = LoadIcon (NULL, IDI_WINLOGO);        // Icon handle
   wc.hCursor = LoadCursor (NULL, IDC_ARROW);      // Cursor handle
   wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); // Background color
   wc.lpszMenuName = NULL;                         // Menu name
   wc.lpszClassName = "MyWndClass";                // WNDCLASS name

   RegisterClass(&wc);
   hWnd = 
      CreateWindow (
         "MyWndClass",            // WNDCLASS name
         "RegisterApplication",   // Window title
         WS_OVERLAPPEDWINDOW,     // Window style
         CW_USEDEFAULT,           // Horizontal position
         CW_USEDEFAULT,           // Vertical position        
         CW_USEDEFAULT,           // Initial width
         CW_USEDEFAULT,           // Initial height
         HWND_MESSAGE,            // HWND_DESKTOP, Handle of parent window
         NULL,                    // Menu handle
         NULL,                    // Application's instance handle
         NULL                     // Window-creation data
         );

   // register for wts notifications.
   if ( ! WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_ALL_SESSIONS) )
   {
      printf("WTSRegisterSessionNotification failed");
      return -1;
   }

   while ( GetMessage(&msg, NULL, 0, 0) )
   {
      TranslateMessage( &msg );
      DispatchMessage( &msg );
   }

   WTSUnRegisterSessionNotification(hWnd);
   return msg.wParam;
}


int main()
{
   HANDLE hThread;
   DWORD dwId;

   // create a thread, wait for notificatons.
   hThread = CreateThread( NULL, 0, fnWaitForWtsNotifs, NULL, 0, &dwId);
   if (NULL == hThread) { return -1; }

   hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
   if (INVALID_HANDLE_VALUE == hEvent) { return -1; }
   WaitForSingleObject(hEvent, INFINITE);
   CloseHandle(hEvent);

   printf("exiting");

   return 0;
}

[-- Attachment #3: Type: text/plain, Size: 204 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-08-20 10:04 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-20 10:04 How to get notifications about system lock/unlock on Windows machine? Yuva

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).